yes, I'm very commit lazy
This commit is contained in:
@@ -1,60 +0,0 @@
|
||||
local setmetatable = setmetatable
|
||||
local base = require("wibox.widget.base")
|
||||
local gtable = require("gears.table")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local module = { mt = {} }
|
||||
|
||||
function module:layout(_, width, height)
|
||||
if self._private.widget then
|
||||
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
|
||||
end
|
||||
end
|
||||
|
||||
function module:fit(context, width, height)
|
||||
local w, h = 0, 0
|
||||
if self._private.widget then
|
||||
w, h = base.fit_widget(self, context, self._private.widget, width, height)
|
||||
end
|
||||
return w, h
|
||||
end
|
||||
|
||||
module.set_widget = base.set_widget_common
|
||||
|
||||
function module:set_widget_template(widget_template)
|
||||
self._private.widget_template = widget_template
|
||||
self:set_widget(widget_template)
|
||||
end
|
||||
|
||||
function module:get_widget()
|
||||
return self._private.widget
|
||||
end
|
||||
|
||||
function module:get_children()
|
||||
return { self._private.widget }
|
||||
end
|
||||
|
||||
function module:set_children(children)
|
||||
self:set_widget(children[1])
|
||||
end
|
||||
|
||||
function module:reset()
|
||||
self._private.widget_template = nil
|
||||
self:set_widget(nil)
|
||||
end
|
||||
|
||||
local function new(args)
|
||||
local self = base.make_widget(nil, nil, { enable_properties = true })
|
||||
|
||||
gtable.crush(self, module, true)
|
||||
|
||||
self:set_widget(wibox.widget.textbox("Hello World!"))
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function module.mt:__call(...)
|
||||
return new(...)
|
||||
end
|
||||
|
||||
return setmetatable(module, module.mt)
|
||||
@@ -3,26 +3,31 @@
|
||||
--------------------------------------
|
||||
|
||||
-- Awesome libs
|
||||
local abutton = require("awful.button")
|
||||
local aspawn = require("awful.spawn")
|
||||
local base = require("wibox.widget.base")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gcolor = require("gears.color")
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local Gio = require("lgi").Gio
|
||||
local gtable = require("gears.table")
|
||||
local wibox = require("wibox")
|
||||
local abutton = require('awful.button')
|
||||
local aspawn = require('awful.spawn')
|
||||
local base = require('wibox.widget.base')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears').filesystem
|
||||
local Gio = require('lgi').Gio
|
||||
local gtable = require('gears.table')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Third party libs
|
||||
local json = require("src.lib.json-lua.json-lua")
|
||||
local cm = require("src.modules.context_menu.init")
|
||||
|
||||
local cm = require('src.modules.context_menu.init')
|
||||
local dock = require('src.modules.crylia_bar.dock')
|
||||
|
||||
-- Local libs
|
||||
local config = require('src.tools.config')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/context_menu/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/context_menu/'
|
||||
|
||||
local application_grid = { mt = {} }
|
||||
|
||||
@@ -31,11 +36,11 @@ local application_grid = { mt = {} }
|
||||
This is done here once because it would be unnecessary to do it for every instance
|
||||
]]
|
||||
do
|
||||
local dir = gfilesystem.get_configuration_dir() .. "src/config"
|
||||
local dir = gfilesystem.get_configuration_dir() .. 'src/config'
|
||||
gfilesystem.make_directories(dir)
|
||||
dir = dir .. "/applications.json"
|
||||
dir = dir .. '/applications.json'
|
||||
if not gfilesystem.file_readable(dir) then
|
||||
aspawn("touch " .. dir)
|
||||
aspawn('touch ' .. dir)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -125,55 +130,55 @@ local function get_applications_from_file()
|
||||
{
|
||||
{
|
||||
{ -- Icon
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = Get_gicon_path(app_info.get_icon(app)) or
|
||||
Get_gicon_path(app_info.get_icon(app),
|
||||
Gio.DesktopAppInfo.get_string(desktop_app_info, "X-AppImage-Old-Icon")) or "",
|
||||
Gio.DesktopAppInfo.get_string(desktop_app_info, 'X-AppImage-Old-Icon')) or '',
|
||||
resize = true,
|
||||
widget = wibox.widget.imagebox
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
height = dpi(64),
|
||||
width = dpi(64),
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
{ -- Name
|
||||
text = app_info.get_name(app),
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = dpi(170),
|
||||
-- Prevents widget from overflowing
|
||||
height = dpi(40),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
name = app_info.get_name(app),
|
||||
comment = Gio.DesktopAppInfo.get_string(desktop_app_info, "Comment") or "",
|
||||
exec = Gio.DesktopAppInfo.get_string(desktop_app_info, "Exec"),
|
||||
keywords = Gio.DesktopAppInfo.get_string(desktop_app_info, "Keywords") or "",
|
||||
categories = Gio.DesktopAppInfo.get_categories(desktop_app_info) or "",
|
||||
terminal = Gio.DesktopAppInfo.get_string(desktop_app_info, "Terminal") == "true",
|
||||
comment = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Comment') or '',
|
||||
exec = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Exec'),
|
||||
keywords = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Keywords') or '',
|
||||
categories = Gio.DesktopAppInfo.get_categories(desktop_app_info) or '',
|
||||
terminal = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Terminal') == 'true',
|
||||
actions = Gio.DesktopAppInfo.list_actions(desktop_app_info),
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or "",
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or '',
|
||||
border_color = Theme_config.application_launcher.application.border_color,
|
||||
border_width = Theme_config.application_launcher.application.border_width,
|
||||
bg = Theme_config.application_launcher.application.bg,
|
||||
fg = Theme_config.application_launcher.application.fg,
|
||||
shape = Theme_config.application_launcher.application.shape,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
local context_menu = cm {
|
||||
widget_template = wibox.widget {
|
||||
@@ -183,122 +188,113 @@ local function get_applications_from_file()
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'text_role',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
entries = {
|
||||
{
|
||||
name = "Execute as sudo",
|
||||
icon = gcolor.recolor_image(icondir .. "launch.svg",
|
||||
name = 'Execute as sudo',
|
||||
icon = gcolor.recolor_image(icondir .. 'launch.svg',
|
||||
Theme_config.application_launcher.application.cm_icon_color),
|
||||
callback = function()
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
aspawn("/home/crylia/.config/awesome/src/scripts/start_as_admin.sh " .. app_widget.exec)
|
||||
end
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
aspawn('/home/crylia/.config/awesome/src/scripts/start_as_admin.sh ' .. app_widget.exec)
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Pin to dock",
|
||||
icon = gcolor.recolor_image(icondir .. "pin.svg",
|
||||
name = 'Pin to dock',
|
||||
icon = gcolor.recolor_image(icondir .. 'pin.svg',
|
||||
Theme_config.application_launcher.application.cm_icon_color),
|
||||
callback = function()
|
||||
-- Open dock.js and read all its content into a table, add the new app into the table and write it back
|
||||
local file_path = gfilesystem.get_configuration_dir() .. "src/config/dock.json"
|
||||
local handler = io.open(file_path, "r")
|
||||
if not handler then return end
|
||||
--[[ async.read_json(gfilesystem.get_configuration_dir() .. 'src/config/dock.json', function(data)
|
||||
table.insert(data, {
|
||||
name = app_widget.name or '',
|
||||
icon = Get_gicon_path(app_info.get_icon(app)) or
|
||||
Get_gicon_path(app_info.get_icon(app),
|
||||
Gio.DesktopAppInfo.get_string(desktop_app_info, 'X-AppImage-Old-Icon')) or '',
|
||||
comment = app_widget.comment or '',
|
||||
exec = app_widget.exec or '',
|
||||
keywords = app_widget.keywords or '',
|
||||
categories = app_widget.categories or '',
|
||||
terminal = app_widget.terminal or '',
|
||||
actions = app_widget.actions or '',
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or ''
|
||||
})
|
||||
|
||||
local dock_table = json:decode(handler:read("a")) or {}
|
||||
|
||||
handler:close()
|
||||
assert(type(dock_table) == "table", "dock_table is not a table")
|
||||
|
||||
table.insert(dock_table, {
|
||||
name = app_widget.name or "",
|
||||
icon = Get_gicon_path(app_info.get_icon(app)) or
|
||||
Get_gicon_path(app_info.get_icon(app),
|
||||
Gio.DesktopAppInfo.get_string(desktop_app_info, "X-AppImage-Old-Icon")) or "",
|
||||
comment = app_widget.comment or "",
|
||||
exec = app_widget.exec or "",
|
||||
keywords = app_widget.keywords or "",
|
||||
categories = app_widget.categories or "",
|
||||
terminal = app_widget.terminal or "",
|
||||
actions = app_widget.actions or "",
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or ""
|
||||
})
|
||||
|
||||
local dock_encoded = json:encode(dock_table)
|
||||
handler = io.open(file_path, "w")
|
||||
|
||||
if not handler then return end
|
||||
|
||||
handler:write(dock_encoded)
|
||||
handler:close()
|
||||
capi.awesome.emit_signal("dock::changed")
|
||||
end
|
||||
async.write_json(gfilesystem.get_configuration_dir() .. 'src/config/dock.json', data, function()
|
||||
capi.awesome.emit_signal('dock::changed')
|
||||
end)
|
||||
end) ]]
|
||||
dock:get_dock_for_screen(capi.mouse.screen):pin_element {
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or '',
|
||||
}
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Add to desktop",
|
||||
icon = gcolor.recolor_image(icondir .. "desktop.svg",
|
||||
name = 'Add to desktop',
|
||||
icon = gcolor.recolor_image(icondir .. 'desktop.svg',
|
||||
Theme_config.application_launcher.application.cm_icon_color),
|
||||
callback = function()
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
capi.awesome.emit_signal("desktop::add_to_desktop", {
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
capi.awesome.emit_signal('desktop::add_to_desktop', {
|
||||
label = app_info.get_name(app),
|
||||
icon = Get_gicon_path(app_info.get_icon(app)) or "",
|
||||
exec = Gio.DesktopAppInfo.get_string(desktop_app_info, "Exec"),
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or ""
|
||||
icon = Get_gicon_path(app_info.get_icon(app)) or '',
|
||||
exec = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Exec'),
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or '',
|
||||
})
|
||||
end
|
||||
}
|
||||
}
|
||||
end,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- Hide context menu when the mouse leaves it
|
||||
context_menu:connect_signal("mouse::leave", function()
|
||||
context_menu:connect_signal('mouse::leave', function()
|
||||
context_menu.visible = false
|
||||
end)
|
||||
|
||||
-- Execute command on left click and hide launcher, right click to show context menu
|
||||
app_widget:buttons(
|
||||
gtable.join(
|
||||
abutton({
|
||||
abutton {
|
||||
modifiers = {},
|
||||
button = 1,
|
||||
on_release = function()
|
||||
Gio.AppInfo.launch_uris_async(app)
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
end
|
||||
}),
|
||||
abutton({
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
end,
|
||||
},
|
||||
abutton {
|
||||
modifiers = {},
|
||||
button = 3,
|
||||
on_release = function()
|
||||
context_menu:toggle()
|
||||
end
|
||||
})
|
||||
end,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
Hover_signal(app_widget)
|
||||
hover.bg_hover { widget = app_widget }
|
||||
table.insert(list, app_widget)
|
||||
end
|
||||
end
|
||||
@@ -308,48 +304,41 @@ end
|
||||
---Takes the search filter and returns a list of applications in the correct order
|
||||
---@param search_filter any
|
||||
function application_grid:set_applications(search_filter)
|
||||
local filter = search_filter or self.filter or ""
|
||||
local filter = search_filter or self.filter or ''
|
||||
-- Reset to first position
|
||||
self._private.curser = {
|
||||
x = 1,
|
||||
y = 1
|
||||
y = 1,
|
||||
}
|
||||
|
||||
local grid = wibox.widget {
|
||||
homogenous = true,
|
||||
expand = false,
|
||||
spacing = dpi(10),
|
||||
id = "grid",
|
||||
id = 'grid',
|
||||
-- 200 is the application element width + 10 spacing
|
||||
forced_num_cols = math.floor((capi.mouse.screen.geometry.width / 100 * 60) / 200),
|
||||
forced_num_rows = 7,
|
||||
orientation = "vertical",
|
||||
layout = wibox.layout.grid
|
||||
orientation = 'vertical',
|
||||
layout = wibox.layout.grid,
|
||||
}
|
||||
|
||||
-- Read the dock.json file and get all apps, these are needed to read/write the launch count
|
||||
local handler = io.open(gfilesystem.get_configuration_dir() .. "src/config/applications.json", "r")
|
||||
if not handler then return end
|
||||
|
||||
local dock_encoded = handler:read("a") or "{}"
|
||||
local dock = json:decode(dock_encoded)
|
||||
|
||||
assert(type(dock) == "table", "dock is not a table")
|
||||
|
||||
local data = config.read_json(gfilesystem.get_configuration_dir() .. 'src/config/applications.json')
|
||||
local mylist = {}
|
||||
|
||||
for _, application in ipairs(self.app_list) do
|
||||
-- Match the filter for the name, categories and keywords
|
||||
if string.match(string.lower(application.name or ""), string.lower(filter)) or
|
||||
string.match(string.lower(application.categories or ""), string.lower(filter)) or
|
||||
string.match(string.lower(application.keywords or ""), string.lower(filter)) then
|
||||
if string.match(string.lower(application.name or ''), string.lower(filter)) or
|
||||
string.match(string.lower(application.categories or ''), string.lower(filter)) or
|
||||
string.match(string.lower(application.keywords or ''), string.lower(filter)) then
|
||||
|
||||
-- If there are no elements in the table, set everything to 0
|
||||
if #dock == 0 then
|
||||
if #data == 0 then
|
||||
application.counter = 0
|
||||
end
|
||||
-- Read the counter for the matching app
|
||||
for _, app in ipairs(dock) do
|
||||
for _, app in ipairs(data) do
|
||||
if app.desktop_file == application.desktop_file then
|
||||
application.counter = app.counter or 0
|
||||
break;
|
||||
@@ -380,7 +369,7 @@ function application_grid:set_applications(search_filter)
|
||||
|
||||
-- Check if the curser is currently at the same position as the app
|
||||
capi.awesome.connect_signal(
|
||||
"update::selected",
|
||||
'update::selected',
|
||||
function()
|
||||
if self._private.curser.y == pos.row and self._private.curser.x == pos.col then
|
||||
app.border_color = Theme_config.application_launcher.application.border_color_active
|
||||
@@ -391,7 +380,7 @@ function application_grid:set_applications(search_filter)
|
||||
)
|
||||
end
|
||||
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
self:set_widget(grid)
|
||||
end
|
||||
|
||||
@@ -401,7 +390,7 @@ function application_grid:move_up()
|
||||
if self._private.curser.y < 1 then
|
||||
self._private.curser.y = 1
|
||||
end
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
end
|
||||
|
||||
-- Move the curser down by one, making sure it doesn't go out of bounds
|
||||
@@ -411,7 +400,7 @@ function application_grid:move_down()
|
||||
if self._private.curser.y > grid_rows then
|
||||
self._private.curser.y = grid_rows
|
||||
end
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
end
|
||||
|
||||
-- Move the curser left by one, making sure it doesn't go out of bounds
|
||||
@@ -420,7 +409,7 @@ function application_grid:move_left()
|
||||
if self._private.curser.x < 1 then
|
||||
self._private.curser.x = 1
|
||||
end
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
end
|
||||
|
||||
-- Move the curser right by one, making sure it doesn't go out of bounds
|
||||
@@ -430,7 +419,7 @@ function application_grid:move_right()
|
||||
if self._private.curser.x > grid_cols then
|
||||
self._private.curser.x = grid_cols
|
||||
end
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
end
|
||||
|
||||
--- Execute the currently selected app and add to the launch count
|
||||
@@ -441,17 +430,9 @@ function application_grid:execute()
|
||||
-- Launch the application async
|
||||
Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(selected_widget.exec, nil, 0))
|
||||
|
||||
local file_path = gfilesystem.get_configuration_dir() .. "src/config/applications.json"
|
||||
local handler = io.open(file_path, "r")
|
||||
if not handler then return end
|
||||
|
||||
local dock_encoded = handler:read("a") or "{}"
|
||||
local dock = json:decode(dock_encoded)
|
||||
|
||||
assert(type(dock) == "table", "dock is not a table")
|
||||
|
||||
local data = config.read_json(gfilesystem.get_configuration_dir() .. 'src/config/applications.json')
|
||||
-- Increase the counter by one then rewrite to the file, its a bit hacky but it works
|
||||
for _, prog in ipairs(dock) do
|
||||
for _, prog in ipairs(data) do
|
||||
if prog.desktop_file:match(selected_widget.desktop_file) then
|
||||
prog.counter = prog.counter + 1
|
||||
-- I don't like goto's, but its the easiest way here(PR is welcome).
|
||||
@@ -462,25 +443,21 @@ function application_grid:execute()
|
||||
local prog = {
|
||||
name = selected_widget.name,
|
||||
desktop_file = selected_widget.desktop_file,
|
||||
counter = 1
|
||||
counter = 1,
|
||||
}
|
||||
table.insert(dock, prog)
|
||||
table.insert(data, prog)
|
||||
end
|
||||
::continue::
|
||||
handler:close()
|
||||
handler = io.open(file_path, "w")
|
||||
if not handler then return end
|
||||
handler:write(json:encode_pretty(dock))
|
||||
handler:close()
|
||||
config.write_json(gfilesystem.get_configuration_dir() .. 'src/config/applications.json', data)
|
||||
end
|
||||
|
||||
-- Reset the grid cursor
|
||||
function application_grid:reset()
|
||||
self._private.curser = {
|
||||
x = 1,
|
||||
y = 1
|
||||
y = 1,
|
||||
}
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
end
|
||||
|
||||
function application_grid.new(args)
|
||||
@@ -496,8 +473,4 @@ function application_grid.new(args)
|
||||
return w
|
||||
end
|
||||
|
||||
function application_grid.mt:__call(...)
|
||||
return application_grid.new(...)
|
||||
end
|
||||
|
||||
return setmetatable(application_grid, application_grid.mt)
|
||||
return setmetatable(application_grid, { __call = function(...) return application_grid.new(...) end })
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
--------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require("awful.button")
|
||||
local akeygrabber = require("awful.keygrabber")
|
||||
local aplacement = require("awful.placement")
|
||||
local apopup = require("awful.popup")
|
||||
local awidget = require("awful.widget")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears.table")
|
||||
local wibox = require("wibox")
|
||||
local abutton = require('awful.button')
|
||||
local akeygrabber = require('awful.keygrabber')
|
||||
local aplacement = require('awful.placement')
|
||||
local apopup = require('awful.popup')
|
||||
local awidget = require('awful.widget')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gtable = require('gears.table')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Own libs
|
||||
local app_grid = require("src.modules.application_launcher.application")
|
||||
local app_grid = require('src.modules.application_launcher.application')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
@@ -23,18 +23,17 @@ local capi = {
|
||||
-- This grid object is shared to avoid having multipe unnecessary instances
|
||||
local application_grid = app_grid {}
|
||||
|
||||
local application_launcher = { mt = {} }
|
||||
local application_launcher = {}
|
||||
|
||||
function application_launcher.new(args)
|
||||
args = args or {}
|
||||
|
||||
-- Create a new inputbox
|
||||
local searchbar = awidget.inputbox {
|
||||
hint_text = "Search...",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
hint_text = 'Search...',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
}
|
||||
|
||||
-- Application launcher popup
|
||||
local application_container = apopup {
|
||||
widget = {
|
||||
@@ -48,7 +47,7 @@ function application_launcher.new(args)
|
||||
margins = 5,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
height = dpi(50),
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
@@ -57,22 +56,22 @@ function application_launcher.new(args)
|
||||
border_color = Theme_config.application_launcher.searchbar.border_color,
|
||||
border_width = Theme_config.application_launcher.searchbar.border_width,
|
||||
shape = Theme_config.application_launcher.searchbar.shape,
|
||||
id = "searchbar_bg"
|
||||
id = 'searchbar_bg',
|
||||
},
|
||||
{
|
||||
application_grid,
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
step = dpi(100),
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
height = args.screen.geometry.height / 100 * 60,
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
ontop = true,
|
||||
@@ -82,7 +81,7 @@ function application_launcher.new(args)
|
||||
placement = aplacement.centered,
|
||||
bg = Theme_config.application_launcher.bg,
|
||||
border_color = Theme_config.application_launcher.border_color,
|
||||
border_width = Theme_config.application_launcher.border_width
|
||||
border_width = Theme_config.application_launcher.border_width,
|
||||
}
|
||||
|
||||
gtable.crush(application_container, application_launcher, true)
|
||||
@@ -91,31 +90,31 @@ function application_launcher.new(args)
|
||||
searchbar:buttons(gtable.join {
|
||||
abutton({}, 1, function()
|
||||
searchbar:focus()
|
||||
end)
|
||||
end),
|
||||
})
|
||||
|
||||
--#region Hover signals to change the cursor to a text cursor
|
||||
local old_cursor, old_wibox
|
||||
searchbar:connect_signal("mouse::enter", function()
|
||||
searchbar:connect_signal('mouse::enter', function()
|
||||
local wid = capi.mouse.current_wibox
|
||||
if wid then
|
||||
old_cursor, old_wibox = wid.cursor, wid
|
||||
wid.cursor = "xterm"
|
||||
wid.cursor = 'xterm'
|
||||
end
|
||||
end)
|
||||
searchbar:connect_signal("mouse::leave", function()
|
||||
searchbar:connect_signal('mouse::leave', function()
|
||||
old_wibox.cursor = old_cursor
|
||||
old_wibox = nil
|
||||
end)
|
||||
--#endregion
|
||||
|
||||
-- Get a reference to the searchbar background value
|
||||
local searchbar_bg = application_container.widget:get_children_by_id("searchbar_bg")[1]
|
||||
local searchbar_bg = application_container.widget:get_children_by_id('searchbar_bg')[1]
|
||||
|
||||
-- Toggle visible for the application launcher and init the searchbar
|
||||
capi.awesome.connect_signal("application_launcher::show", function()
|
||||
capi.awesome.connect_signal('application_launcher::show', function()
|
||||
if capi.mouse.screen == args.screen then
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
if capi.mouse.screen == args.screen then
|
||||
application_container.visible = not application_container.visible
|
||||
end
|
||||
@@ -123,76 +122,76 @@ function application_launcher.new(args)
|
||||
searchbar_bg.border_color = Theme_config.application_launcher.searchbar.border_active
|
||||
searchbar:focus()
|
||||
else
|
||||
searchbar:set_text("")
|
||||
searchbar:set_text('')
|
||||
akeygrabber.stop()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Execute the currently selected application, reset the searchbar and hide the launcher
|
||||
searchbar:connect_signal("submit", function(_, text)
|
||||
searchbar:connect_signal('submit', function(_, text)
|
||||
application_grid:execute()
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
searchbar:set_text("")
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
searchbar:set_text('')
|
||||
application_grid:set_applications(searchbar:get_text())
|
||||
searchbar_bg.border_color = Theme_config.application_launcher.searchbar.border_color
|
||||
end)
|
||||
|
||||
-- Hide the application launcher when the keygrabber stops and reset the searchbar
|
||||
searchbar:connect_signal("stopped", function(_, stop_key)
|
||||
if stop_key == "Escape" then
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
searchbar:connect_signal('stopped', function(_, stop_key)
|
||||
if stop_key == 'Escape' then
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
end
|
||||
searchbar:set_text("")
|
||||
searchbar:set_text('')
|
||||
application_grid:set_applications(searchbar:get_text())
|
||||
searchbar_bg.border_color = Theme_config.application_launcher.searchbar.border_color
|
||||
end)
|
||||
|
||||
-- When started change the background for the searchbar
|
||||
searchbar:connect_signal("started", function()
|
||||
searchbar:connect_signal('started', function()
|
||||
searchbar_bg.border_color = Theme_config.application_launcher.searchbar.border_active
|
||||
end)
|
||||
|
||||
-- On every keypress in the searchbar check for certain inputs
|
||||
searchbar:connect_signal("inputbox::key_pressed", function(_, modkey, key)
|
||||
if key == "Escape" then -- Escape to stop the keygrabber, hide the launcher and reset the searchbar
|
||||
searchbar:connect_signal('inputbox::key_pressed', function(_, modkey, key)
|
||||
if key == 'Escape' then -- Escape to stop the keygrabber, hide the launcher and reset the searchbar
|
||||
searchbar:stop()
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
application_grid:reset()
|
||||
searchbar:set_text("")
|
||||
elseif key == "Down" or key == "Right" then --If down or right is pressed initiate the grid navigation
|
||||
if key == "Down" then
|
||||
searchbar:set_text('')
|
||||
elseif key == 'Down' or key == 'Right' then --If down or right is pressed initiate the grid navigation
|
||||
if key == 'Down' then
|
||||
application_grid:move_down()
|
||||
elseif key == "Right" then
|
||||
elseif key == 'Right' then
|
||||
application_grid:move_right()
|
||||
end
|
||||
searchbar:stop()
|
||||
--New keygrabber to allow for key navigation
|
||||
akeygrabber.run(function(mod, key2, event)
|
||||
if event == "press" then
|
||||
if key2 == "Down" then
|
||||
if event == 'press' then
|
||||
if key2 == 'Down' then
|
||||
application_grid:move_down()
|
||||
elseif key2 == "Up" then
|
||||
elseif key2 == 'Up' then
|
||||
local old_y = application_grid._private.curser.y
|
||||
application_grid:move_up()
|
||||
if old_y - application_grid._private.curser.y == 0 then
|
||||
searchbar:focus()
|
||||
end
|
||||
elseif key2 == "Left" then
|
||||
elseif key2 == 'Left' then
|
||||
application_grid:move_left()
|
||||
elseif key2 == "Right" then
|
||||
elseif key2 == 'Right' then
|
||||
application_grid:move_right()
|
||||
elseif key2 == "Return" then
|
||||
elseif key2 == 'Return' then
|
||||
akeygrabber.stop()
|
||||
application_grid:execute()
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
application_grid:reset()
|
||||
searchbar:set_text("")
|
||||
searchbar:set_text('')
|
||||
application_grid:set_applications(searchbar:get_text())
|
||||
elseif key2 == "Escape" then
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
elseif key2 == 'Escape' then
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
application_grid:reset()
|
||||
searchbar:set_text("")
|
||||
searchbar:set_text('')
|
||||
application_grid:set_applications(searchbar:get_text())
|
||||
akeygrabber.stop()
|
||||
end
|
||||
@@ -205,8 +204,4 @@ function application_launcher.new(args)
|
||||
end)
|
||||
end
|
||||
|
||||
function application_launcher.mt:__call(...)
|
||||
return application_launcher.new(...)
|
||||
end
|
||||
|
||||
return setmetatable(application_launcher, application_launcher.mt)
|
||||
return setmetatable(application_launcher, { __call = function(_, ...) return application_launcher.new(...) end })
|
||||
|
||||
575
awesome/src/modules/audio/audio_controller.lua
Normal file
575
awesome/src/modules/audio/audio_controller.lua
Normal file
@@ -0,0 +1,575 @@
|
||||
-- Awesome Libs
|
||||
local abutton = require('awful.button')
|
||||
local aspawn = require('awful.spawn')
|
||||
local base = require('wibox.widget.base')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gshape = require('gears.shape')
|
||||
local gtable = require('gears.table')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Third party libs
|
||||
local rubato = require('src.lib.rubato')
|
||||
|
||||
-- Local libs
|
||||
local audio_helper = require('src.tools.helpers.audio')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/audio/'
|
||||
|
||||
local audio_controller = {}
|
||||
|
||||
--#region wibox.widget.base boilerplate
|
||||
|
||||
function audio_controller:layout(_, width, height)
|
||||
if self._private.widget then
|
||||
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
|
||||
end
|
||||
end
|
||||
|
||||
function audio_controller:fit(context, width, height)
|
||||
local w, h = 0, 0 ---@type number|nil, number|nil
|
||||
if self._private.widget then
|
||||
w, h = base.fit_widget(self, context, self._private.widget, width, height)
|
||||
end
|
||||
return w, h
|
||||
end
|
||||
|
||||
--#endregion
|
||||
|
||||
---Set the default source asynchronously
|
||||
---@param sink any
|
||||
function audio_controller:set_default_sink(sink)
|
||||
if not sink then return end
|
||||
aspawn('pactl set-default-sink ' .. sink)
|
||||
self:emit_signal('AC::device_changed')
|
||||
end
|
||||
|
||||
---Set the default source asynchronously
|
||||
function audio_controller:set_default_source(source)
|
||||
if not source then return end
|
||||
aspawn('pactl set-default-source ' .. source)
|
||||
self:emit_signal('AC::device_changed')
|
||||
end
|
||||
|
||||
---Get the default sink asynchronously
|
||||
---@param callback function returns the default sink as string
|
||||
function audio_controller:get_default_sink_async(callback)
|
||||
aspawn.easy_async_with_shell('pactl get-default-sink', function(stdout) callback(stdout:gsub('\n', '')) end)
|
||||
end
|
||||
|
||||
---Takes a sink and name and returns a new device widget, the device_type is for the color
|
||||
---@param device string sink
|
||||
---@param name string name of the device
|
||||
---@param device_type string sink or source
|
||||
---@return wibox.widget
|
||||
function audio_controller:get_device_widget(device, name, device_type)
|
||||
--remove leading spaces from name
|
||||
name = name:gsub('^%s*(.-)%s*$', '%1')
|
||||
local icon_color, fg
|
||||
if device_type == 'source' then
|
||||
icon_color = Theme_config.volume_controller.device_microphone_fg
|
||||
fg = Theme_config.volume_controller.device_microphone_fg
|
||||
elseif device_type == 'sink' then
|
||||
icon_color = Theme_config.volume_controller.device_headphones_fg
|
||||
fg = Theme_config.volume_controller.device_headphones_fg
|
||||
end
|
||||
|
||||
local device_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = 'icon',
|
||||
resize = true,
|
||||
image = gcolor.recolor_image(icondir .. 'volume-high.svg', icon_color),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
{
|
||||
id = 'name',
|
||||
text = name,
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(24),
|
||||
strategy = 'exact',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.volume_controller.device_bg,
|
||||
fg = fg,
|
||||
border_color = Theme_config.volume_controller.device_border_color,
|
||||
border_width = Theme_config.volume_controller.device_border_width,
|
||||
shape = Theme_config.volume_controller.device_shape,
|
||||
widget = wibox.container.background,
|
||||
sink = device,
|
||||
}
|
||||
|
||||
if device_type == 'sink' then
|
||||
device_widget:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
self:set_default_sink(device)
|
||||
end)
|
||||
))
|
||||
elseif device_type == 'source' then
|
||||
device_widget:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
self:set_default_source(device)
|
||||
end)
|
||||
))
|
||||
end
|
||||
|
||||
self:connect_signal('AC::device_changed', function(new_sink)
|
||||
if device_widget.device == new_sink then
|
||||
device_widget.bg = Theme_config.volume_controller.device_headphones_selected_bg
|
||||
device_widget.fg = Theme_config.volume_controller.device_headphones_selected_fg
|
||||
device_widget:get_children_by_id('icon')[1].image = gcolor.recolor_image(icondir .. 'volume-high.svg', Theme_config.volume_controller.device_headphones_selected_fg)
|
||||
else
|
||||
device_widget.bg = Theme_config.volume_controller.device_bg
|
||||
device_widget.fg = fg
|
||||
device_widget:get_children_by_id('icon')[1].image = gcolor.recolor_image(icondir .. 'volume-high.svg', icon_color)
|
||||
end
|
||||
end)
|
||||
|
||||
hover.bg_hover { widget = device_widget }
|
||||
|
||||
return device_widget
|
||||
end
|
||||
|
||||
---Get all sink devices
|
||||
---@param callback function returns a list of sinks
|
||||
function audio_controller:get_sink_devices_async(callback)
|
||||
-- This command gets all audio sources and their descriptions in this format: "source_name;source_description\n"
|
||||
aspawn.easy_async_with_shell([=[
|
||||
LC_ALL=C pactl list sinks | awk '/Name:/ { name=$0 } /Description:/ { sub(/Name: /, "", name); sub(/Description: /, "", $0); print name ";" $0 }'
|
||||
]=], function(stdout)
|
||||
local sinks = wibox.layout.fixed.vertical {}
|
||||
for line in stdout:gmatch('[^\r\n]+') do
|
||||
-- Call the callback function with the name and description
|
||||
local s, n = line:match('(.-);(.+)')
|
||||
table.insert(sinks, self:get_device_widget(s, n, 'sink'))
|
||||
end
|
||||
self.sinks = sinks
|
||||
callback()
|
||||
end)
|
||||
end
|
||||
|
||||
---Get all source devices
|
||||
---@param callback function returns a list of sources
|
||||
function audio_controller:get_source_devices_async(callback)
|
||||
-- This command gets all audio sources and their descriptions in this format: "source_name;source_description\n"
|
||||
aspawn.easy_async_with_shell([=[
|
||||
LC_ALL=C pactl list sources | awk '/Name:/ { name=$0 } /Description:/ { sub(/Name: /, "", name); sub(/Description: /, "", $0); print name ";" $0 }'
|
||||
]=], function(stdout)
|
||||
local sources = wibox.layout.fixed.vertical {}
|
||||
for line in stdout:gmatch('[^\r\n]+') do
|
||||
local s, n = line:match('(.-);(.+)')
|
||||
table.insert(sources, self:get_device_widget(s, n, 'source'))
|
||||
end
|
||||
self.sources = sources
|
||||
callback()
|
||||
end)
|
||||
end
|
||||
|
||||
---Creates a new audio controller
|
||||
---@return wibox.widget auio_controller the audio controller widget
|
||||
function audio_controller.new()
|
||||
local w = base.make_widget_from_value(wibox.widget {
|
||||
{
|
||||
{
|
||||
{ -- sink Device selector
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'sink_dd_icon',
|
||||
},
|
||||
{
|
||||
{
|
||||
text = 'Output Devices',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = 'sink_dd_shape',
|
||||
bg = Theme_config.volume_controller.list_bg,
|
||||
fg = Theme_config.volume_controller.list_headphones_fg,
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
{ -- sink dropdown
|
||||
{
|
||||
{
|
||||
{
|
||||
spacing = dpi(10),
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
step = dpi(50),
|
||||
id = 'sink_list',
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
border_color = Theme_config.volume_controller.list_border_color,
|
||||
border_width = Theme_config.volume_controller.list_border_width,
|
||||
id = 'sink_list_shape',
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
id = 'sink_height',
|
||||
strategy = 'exact',
|
||||
height = 0,
|
||||
width = dpi(300),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{ -- Spacer
|
||||
widget = wibox.container.background,
|
||||
forced_height = dpi(10),
|
||||
},
|
||||
{ -- source Device selector
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'source_dd_icon',
|
||||
},
|
||||
{
|
||||
{
|
||||
text = 'Input Devices',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = 'source_dd_shape',
|
||||
bg = Theme_config.volume_controller.list_bg,
|
||||
fg = Theme_config.volume_controller.list_headphones_fg,
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
{ -- source dropdown
|
||||
{
|
||||
{
|
||||
{
|
||||
spacing = dpi(10),
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
step = dpi(50),
|
||||
id = 'source_list',
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
border_color = Theme_config.volume_controller.list_border_color,
|
||||
border_width = Theme_config.volume_controller.list_border_width,
|
||||
id = 'source_list_shape',
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
id = 'source_height',
|
||||
strategy = 'exact',
|
||||
height = 0,
|
||||
width = dpi(300),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{ -- Spacer
|
||||
widget = wibox.container.background,
|
||||
forced_height = dpi(10),
|
||||
},
|
||||
{ -- sink volume slider
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = true,
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = gcolor.recolor_image(icondir .. 'volume-high.svg', Theme_config.volume_controller.volume_fg),
|
||||
id = 'sink_icon',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(26),
|
||||
height = dpi(26),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
bar_shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(5))
|
||||
end,
|
||||
bar_height = dpi(5),
|
||||
bar_color = Theme_config.volume_controller.border_color,
|
||||
bar_active_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_shape = gshape.circle,
|
||||
handle_border_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_width = dpi(15),
|
||||
handle_cursor = 'left_ptr',
|
||||
maximum = 100,
|
||||
forced_height = 0, -- No idea why its needed but it makes the widget not go into infinity
|
||||
value = 50,
|
||||
widget = wibox.widget.slider,
|
||||
id = 'sink_slider',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(300),
|
||||
height = dpi(26),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{ -- Spacer
|
||||
widget = wibox.container.background,
|
||||
forced_height = dpi(10),
|
||||
},
|
||||
{ -- source volume slider
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = true,
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = gcolor.recolor_image(icondir .. 'microphone.svg', Theme_config.volume_controller.volume_fg),
|
||||
id = 'source_icon',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(26),
|
||||
height = dpi(26),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
bar_shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(5))
|
||||
end,
|
||||
bar_height = dpi(5),
|
||||
bar_color = Theme_config.volume_controller.border_color,
|
||||
bar_active_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_shape = gshape.circle,
|
||||
handle_border_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_width = dpi(15),
|
||||
handle_cursor = 'left_ptr',
|
||||
maximum = 100,
|
||||
forced_height = 0, -- No idea why its needed but it makes the widget not go into infinity
|
||||
value = 50,
|
||||
widget = wibox.widget.slider,
|
||||
id = 'source_slider',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(400),
|
||||
height = dpi(26),
|
||||
strategy = 'exact',
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
margins = dpi(15),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
-- The parent margin doesn't render without an empty widget here???
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
|
||||
assert(w, 'Failed to create volume controller widget')
|
||||
|
||||
gtable.crush(w, audio_controller, true)
|
||||
|
||||
local sink_icon = w:get_children_by_id('sink_icon')[1]
|
||||
local sink_slider = w:get_children_by_id('sink_slider')[1]
|
||||
|
||||
sink_slider:connect_signal('property::value', function(_, value)
|
||||
audio_helper.set_sink_volume(value)
|
||||
end)
|
||||
|
||||
-- Set the volume and icon
|
||||
audio_helper:connect_signal('sink::get', function(_, muted, volume)
|
||||
volume = tonumber(volume)
|
||||
assert(type(muted) == 'boolean' and type(volume) == 'number', 'audio::get signal expects boolean and number')
|
||||
if w.sink_volume == volume and w.sink_muted == muted then return end
|
||||
w.sink_volume = volume
|
||||
w.sink_muted = muted
|
||||
if muted then
|
||||
sink_icon:set_image(gcolor.recolor_image(icondir .. 'volume-mute.svg', Theme_config.volume_controller.volume_fg))
|
||||
else
|
||||
local icon = icondir .. 'volume'
|
||||
if volume == 0 then
|
||||
icon = icon .. '-mute'
|
||||
elseif volume > 0 and volume < 34 then
|
||||
icon = icon .. '-low'
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. '-medium'
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. '-high'
|
||||
end
|
||||
|
||||
sink_slider:set_value(volume)
|
||||
sink_icon:set_image(gcolor.recolor_image(icon .. '.svg', Theme_config.volume_controller.volume_fg))
|
||||
end
|
||||
end)
|
||||
|
||||
local source_icon = w:get_children_by_id('source_icon')[1]
|
||||
local source_slider = w:get_children_by_id('source_slider')[1]
|
||||
|
||||
-- Microphone slider change event
|
||||
source_slider:connect_signal('property::value', function(_, value)
|
||||
audio_helper.set_source_volume(value)
|
||||
end)
|
||||
|
||||
--- Set the source volume and icon
|
||||
audio_helper:connect_signal('source::get', function(_, muted, volume)
|
||||
volume = tonumber(volume)
|
||||
assert(type(muted) == 'boolean' and type(volume) == 'number', 'microphone::get signal expects boolean and number')
|
||||
if w.source_volume == volume and w.source_muted == muted then return end
|
||||
w.source_volume = volume
|
||||
w.source_muted = muted
|
||||
if muted then
|
||||
source_icon:set_image(gcolor.recolor_image(icondir .. 'microphone-off.svg', Theme_config.volume_controller.microphone_fg))
|
||||
else
|
||||
if not volume then return end
|
||||
source_slider:set_value(tonumber(volume))
|
||||
if volume > 0 then
|
||||
source_icon:set_image(gcolor.recolor_image(icondir .. 'microphone.svg', Theme_config.volume_controller.microphone_fg))
|
||||
else
|
||||
source_icon:set_image(gcolor.recolor_image(icondir .. 'microphone-off.svg', Theme_config.volume_controller.microphone_fg))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local sink_dd_shape = w:get_children_by_id('sink_dd_shape')[1]
|
||||
local sink_height = w:get_children_by_id('sink_height')[1]
|
||||
local sink_dd_icon = w:get_children_by_id('sink_dd_icon')[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = sink_height.height,
|
||||
clamp_position = true,
|
||||
subscribed = function(v)
|
||||
sink_height.height = v
|
||||
end,
|
||||
}
|
||||
|
||||
sink_dd_shape:buttons(gtable.join {
|
||||
abutton({}, 1, function()
|
||||
if sink_height.height == 0 then
|
||||
local size = dpi((#w.sinks * 44) + ((#w.sinks - 1) * 10) + 20)
|
||||
|
||||
if #w.sinks > 4 then
|
||||
size = dpi(226)
|
||||
end
|
||||
rubato_timer.target = size
|
||||
|
||||
sink_dd_shape.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
|
||||
sink_dd_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color))
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
|
||||
sink_dd_shape.shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 4)
|
||||
end
|
||||
|
||||
sink_dd_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color))
|
||||
end
|
||||
end),
|
||||
})
|
||||
|
||||
local source_dd_shape = w:get_children_by_id('source_dd_shape')[1]
|
||||
local source_height = w:get_children_by_id('source_height')[1]
|
||||
local source_dd_icon = w:get_children_by_id('source_dd_icon')[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = source_height.height,
|
||||
clamp_position = true,
|
||||
subscribed = function(v)
|
||||
source_height.height = v
|
||||
end,
|
||||
}
|
||||
|
||||
source_dd_shape:buttons(gtable.join {
|
||||
abutton({}, 1, function()
|
||||
if source_height.height == 0 then
|
||||
local size = dpi(((#w.sources * 44) + ((#w.sources - 1) * 10) + 20))
|
||||
|
||||
if #w.sources > 4 then
|
||||
size = dpi(226)
|
||||
end
|
||||
|
||||
rubato_timer.target = size
|
||||
|
||||
source_dd_shape.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
|
||||
source_dd_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color))
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
|
||||
source_dd_shape.shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 4)
|
||||
end
|
||||
|
||||
source_dd_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color))
|
||||
end
|
||||
end),
|
||||
})
|
||||
|
||||
local sink_list = w:get_children_by_id('sink_list')[1]
|
||||
w:get_sink_devices_async(function()
|
||||
sink_list.children = w.sinks
|
||||
end)
|
||||
|
||||
local source_list = w:get_children_by_id('source_list')[1]
|
||||
w:get_source_devices_async(function()
|
||||
source_list.children = w.sources
|
||||
end)
|
||||
|
||||
hover.bg_hover { widget = sink_dd_shape }
|
||||
hover.bg_hover { widget = source_dd_shape }
|
||||
return w
|
||||
end
|
||||
|
||||
return setmetatable(audio_controller, { __call = function() return audio_controller.new() end })
|
||||
@@ -1,553 +0,0 @@
|
||||
-----------------------------------
|
||||
-- This is the volume controller --
|
||||
-----------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local gobject = require("gears.object")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mousegrabber = mousegrabber,
|
||||
}
|
||||
|
||||
local rubato = require("src.lib.rubato")
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/audio/"
|
||||
|
||||
local volume_controler = { mt = {} }
|
||||
|
||||
function volume_controler.get_device_widget()
|
||||
local device = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
spacing = dpi(10),
|
||||
{
|
||||
text = name,
|
||||
id = "node",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "device_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "device_margin",
|
||||
margins = dpi(9),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "background",
|
||||
bg = Theme_config.volume_controller.device_bg,
|
||||
border_color = Theme_config.volume_controller.device_border_color,
|
||||
border_width = Theme_config.volume_controller.device_border_width,
|
||||
shape = Theme_config.volume_controller.device_shape,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
if true then
|
||||
device:connect_signal(
|
||||
"button::press",
|
||||
function(_, _, _, key)
|
||||
if key == 1 then
|
||||
if node then
|
||||
--awful.spawn("./.config/awesome/src/scripts/vol.sh set_sink " .. node)
|
||||
--capi.awesome.emit_signal("update::bg_sink", node)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
--[[ capi.awesome.connect_signal(
|
||||
"update::bg_sink",
|
||||
function(new_node)
|
||||
if node == new_node then
|
||||
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "headphones.svg",
|
||||
Theme_config.volume_controller.device_icon_color)
|
||||
device.bg = Theme_config.volume_controller.device_headphones_selected_bg
|
||||
device.fg = Theme_config.volume_controller.device_headphones_selected_fg
|
||||
Hover_signal(device)
|
||||
else
|
||||
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "headphones.svg",
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color)
|
||||
device.bg = Theme_config.volume_controller.device_bg
|
||||
device.fg = Theme_config.volume_controller.device_headphones_fg
|
||||
Hover_signal(device)
|
||||
end
|
||||
end
|
||||
) ]]
|
||||
else
|
||||
device:connect_signal(
|
||||
"button::press",
|
||||
function(_, _, _, key)
|
||||
if key == 1 then
|
||||
if node then
|
||||
--awful.spawn("./.config/awesome/src/scripts/mic.sh set_source " .. node)
|
||||
--capi.awesome.emit_signal("update::bg_source", node)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
--[[ capi.awesome.connect_signal(
|
||||
"update::bg_source",
|
||||
function(new_node)
|
||||
if node == new_node then
|
||||
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "microphone.svg",
|
||||
Theme_config.volume_controller.device_icon_color)
|
||||
device.bg = Theme_config.volume_controller.device_microphone_selected_bg
|
||||
device.fg = Theme_config.volume_controller.device_microphone_selected_fg
|
||||
Hover_signal(device)
|
||||
else
|
||||
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "microphone.svg",
|
||||
Theme_config.volume_controller.device_microphone_selected_icon_color)
|
||||
device.bg = Theme_config.volume_controller.device_bg
|
||||
device.fg = Theme_config.volume_controller.device_microphone_fg
|
||||
Hover_signal(device)
|
||||
end
|
||||
end
|
||||
) ]]
|
||||
end
|
||||
return device
|
||||
end
|
||||
|
||||
-- Get all source devices
|
||||
function volume_controler:get_source_devices()
|
||||
|
||||
end
|
||||
|
||||
-- Get all input devices
|
||||
function volume_controler:get_input_devices()
|
||||
|
||||
end
|
||||
|
||||
function volume_controler:toggle()
|
||||
volume_controler.popup.visible = not volume_controler.popup.visible
|
||||
end
|
||||
|
||||
function volume_controler.run(args)
|
||||
|
||||
args = args or {}
|
||||
|
||||
local ret = gobject {}
|
||||
|
||||
local w = wibox.widget {
|
||||
{
|
||||
{
|
||||
-- Audio Device selector
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gears.color.recolor_image(icondir .. "menu-down.svg",
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon"
|
||||
},
|
||||
id = "center",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{
|
||||
{
|
||||
text = "Output Device",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "device_name"
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "audio_volume",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "audio_bg",
|
||||
bg = Theme_config.volume_controller.list_bg,
|
||||
fg = Theme_config.volume_controller.list_headphones_fg,
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "audio_selector_margin",
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
top = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
id = "volume_list",
|
||||
widget = {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
spacing = dpi(10),
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
scrollbar_width = 0,
|
||||
step = dpi(50),
|
||||
id = "volume_device_list",
|
||||
},
|
||||
id = "margin",
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "place",
|
||||
height = dpi(200),
|
||||
strategy = "max",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
border_color = Theme_config.volume_controller.list_border_color,
|
||||
border_width = Theme_config.volume_controller.list_border_width,
|
||||
id = "volume_device_background",
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
forced_height = 0
|
||||
},
|
||||
-- Microphone selector
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gears.color.recolor_image(icondir .. "menu-down.svg",
|
||||
Theme_config.volume_controller.device_microphone_selected_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon",
|
||||
},
|
||||
id = "center",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{
|
||||
{
|
||||
text = "Input Device",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "device_name"
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "mic_volume",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "mic_bg",
|
||||
bg = Theme_config.volume_controller.list_bg,
|
||||
fg = Theme_config.volume_controller.list_microphone_fg,
|
||||
shape = Theme_config.volume_controller.selector_shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "mic_selector_margin",
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
top = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
id = "mic_list",
|
||||
widget = {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
spacing = dpi(10),
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
id = "volume_device_list",
|
||||
scrollbar_width = 0,
|
||||
step = dpi(50),
|
||||
},
|
||||
id = "margin",
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "place",
|
||||
height = dpi(200),
|
||||
strategy = "max",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "volume_device_background",
|
||||
border_color = Theme_config.volume_controller.list_border_color,
|
||||
border_width = Theme_config.volume_controller.list_border_width,
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
forced_height = 0
|
||||
},
|
||||
-- Audio volume slider
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "volume-high.svg", Theme_config.volume_controller.volume_fg),
|
||||
id = "icon",
|
||||
},
|
||||
{
|
||||
{
|
||||
bar_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(5))
|
||||
end,
|
||||
bar_height = dpi(5),
|
||||
bar_color = Theme_config.volume_controller.border_color,
|
||||
bar_active_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_shape = gears.shape.circle,
|
||||
handle_border_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_width = dpi(12),
|
||||
maximum = 100,
|
||||
forced_height = dpi(26),
|
||||
widget = wibox.widget.slider,
|
||||
id = "slider"
|
||||
},
|
||||
left = dpi(5),
|
||||
id = "slider_margin",
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "audio_volume",
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
id = "audio_volume_margin",
|
||||
top = dpi(10),
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
-- Microphone volume slider
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "microphone.svg", Theme_config.volume_controller.microphone_fg),
|
||||
id = "icon"
|
||||
},
|
||||
{
|
||||
{
|
||||
bar_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(5))
|
||||
end,
|
||||
bar_height = dpi(5),
|
||||
bar_color = Theme_config.volume_controller.device_border_color,
|
||||
bar_active_color = Theme_config.volume_controller.microphone_fg,
|
||||
handle_color = Theme_config.volume_controller.microphone_fg,
|
||||
handle_shape = gears.shape.circle,
|
||||
handle_border_color = Theme_config.volume_controller.microphone_fg,
|
||||
handle_width = dpi(12),
|
||||
maximum = 100,
|
||||
forced_height = dpi(26),
|
||||
widget = wibox.widget.slider,
|
||||
id = "slider"
|
||||
},
|
||||
left = dpi(5),
|
||||
id = "slider_margin",
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "mic_volume",
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
id = "mic_volume_margin",
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
top = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "controller_layout",
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
id = "controller_margin",
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
bg = Theme_config.volume_controller.bg,
|
||||
border_color = Theme_config.volume_controller.border_color,
|
||||
border_width = Theme_config.volume_controller.border_width,
|
||||
shape = Theme_config.volume_controller.shape,
|
||||
forced_width = dpi(400),
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
ret.widget = w
|
||||
ret.audio_dropdown = w:get_children_by_id("audio_list")[1]
|
||||
ret.mic_dropdown = w:get_children_by_id("mic_list")[1]
|
||||
ret.audio_slider = w:get_children_by_id("slider")[1]
|
||||
ret.mic_slider = w:get_children_by_id("slider")[1]
|
||||
|
||||
-- Main container
|
||||
ret.popup = awful.popup {
|
||||
widget = w,
|
||||
ontop = true,
|
||||
bg = Theme_config.volume_controller.bg,
|
||||
stretch = false,
|
||||
visible = false,
|
||||
screen = args.screen,
|
||||
--! Calculate the popup position instead of hardcoding it
|
||||
placement = function(c) awful.placement.align(c,
|
||||
{ position = "top_right", margins = { right = dpi(305), top = dpi(60) } })
|
||||
end,
|
||||
shape = Theme_config.volume_controller.shape,
|
||||
}
|
||||
|
||||
-- Set the volume and icon
|
||||
capi.awesome.connect_signal(
|
||||
"audio::get",
|
||||
function(muted, volume)
|
||||
if muted then
|
||||
volume_controller.controller_margin.controller_layout.audio_volume_margin.audio_volume.icon:set_image(gears.color
|
||||
.recolor_image(icondir .. "volume-mute.svg", Theme_config.volume_controller.volume_fg))
|
||||
else
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
local icon = icondir .. "volume"
|
||||
if volume < 1 then
|
||||
icon = icon .. "-mute"
|
||||
elseif volume >= 1 and volume < 34 then
|
||||
icon = icon .. "-low"
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. "-medium"
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. "-high"
|
||||
end
|
||||
|
||||
volume_controller.controller_margin.controller_layout.audio_volume_margin.audio_volume.slider_margin.slider:
|
||||
set_value(volume)
|
||||
volume_controller.controller_margin.controller_layout.audio_volume_margin.audio_volume.icon:set_image(gears.color
|
||||
.recolor_image(icon
|
||||
.. ".svg", Theme_config.volume_controller.volume_fg))
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- Get microphone volume
|
||||
capi.awesome.connect_signal(
|
||||
"microphone::get",
|
||||
function(muted, volume)
|
||||
if muted then
|
||||
--volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.slider_margin.slider:set_value(tonumber(0))
|
||||
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir
|
||||
.. "microphone-off.svg", Theme_config.volume_controller.microphone_fg))
|
||||
else
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.slider_margin.slider:set_value(tonumber(volume))
|
||||
if volume > 0 then
|
||||
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir
|
||||
.. "microphone.svg", Theme_config.volume_controller.microphone_fg))
|
||||
else
|
||||
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir
|
||||
.. "microphone-off.svg", Theme_config.volume_controller.microphone_fg))
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- Microphone slider change event
|
||||
ret.widget:connect_signal(
|
||||
"property::value",
|
||||
function()
|
||||
end
|
||||
)
|
||||
|
||||
-- Slide animation
|
||||
ret.audio_dropdown:connect_signal(
|
||||
"button::press",
|
||||
function(_, _, _, key)
|
||||
if key == 1 then
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.4,
|
||||
intro = 0.1,
|
||||
outro = 0.1,
|
||||
pos = mic_list.forced_height,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
mic_list.forced_height = v
|
||||
end
|
||||
}
|
||||
if mic_list.forced_height == 0 then
|
||||
rubato_timer.target = dpi(200)
|
||||
mic_selector_margin.mic_bg.shape = function(cr, width, height)
|
||||
gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
mic_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-up.svg",
|
||||
Theme_config.volume_controller.device_microphone_selected_icon_color))
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
mic_bg.shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(4))
|
||||
end
|
||||
mic_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-down.svg",
|
||||
Theme_config.volume_controller.device_microphone_selected_icon_color))
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- Slide animation
|
||||
ret.mic_dropdown:connect_signal(
|
||||
"button::press",
|
||||
function(_, _, _, key)
|
||||
if key == 1 then
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.4,
|
||||
intro = 0.1,
|
||||
outro = 0.1,
|
||||
pos = volume_list.forced_height,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
volume_list.forced_height = v
|
||||
end
|
||||
}
|
||||
if volume_list.forced_height == 0 then
|
||||
rubato_timer.target = dpi(200)
|
||||
audio_bg.shape = function(cr, width, height)
|
||||
gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
audio_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-up.svg",
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color))
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
audio_bg.shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(4))
|
||||
end
|
||||
audio_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-down.svg",
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color))
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function volume_controler.mt:__call(...)
|
||||
return volume_controler.run(...)
|
||||
end
|
||||
|
||||
return setmetatable(volume_controler, volume_controler.mt)
|
||||
@@ -3,151 +3,136 @@
|
||||
-----------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local gobject = require("gears.object")
|
||||
local aplacement = require('awful.placement')
|
||||
local apopup = require('awful.popup')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gshape = require('gears.shape')
|
||||
local gtable = require('gears.table')
|
||||
local gtimer = require('gears.timer')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
}
|
||||
local audio_helper = require('src.tools.helpers.audio')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/audio/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/audio/'
|
||||
|
||||
local osd = { mt = {} }
|
||||
local osd = {}
|
||||
|
||||
function osd:run()
|
||||
self.visible = true
|
||||
if self.timer.started then
|
||||
self.timer:again()
|
||||
else
|
||||
self.timer:start()
|
||||
end
|
||||
end
|
||||
|
||||
function osd.new(args)
|
||||
args = args or {}
|
||||
args.screen = args.screen or 1
|
||||
|
||||
local ret = gobject {}
|
||||
|
||||
ret.w = wibox.widget {
|
||||
{
|
||||
local w = apopup {
|
||||
widget = {
|
||||
{
|
||||
{ -- Volume Icon
|
||||
image = gears.color.recolor_image(icondir .. "volume-high.svg", Theme_config.volume_osd.icon_color),
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
resize = false,
|
||||
id = "icon",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{ -- Volume Bar
|
||||
{
|
||||
{
|
||||
{ -- Volume Icon
|
||||
{
|
||||
id = "progressbar1",
|
||||
color = Theme_config.volume_osd.bar_bg_active,
|
||||
background_color = Theme_config.volume_osd.bar_bg,
|
||||
max_value = 100,
|
||||
value = 50,
|
||||
forced_height = dpi(6),
|
||||
shape = function(cr, width, heigth)
|
||||
gears.shape.rounded_bar(cr, width, heigth, dpi(6))
|
||||
end,
|
||||
widget = wibox.widget.progressbar
|
||||
image = gcolor.recolor_image(icondir .. 'volume-off.svg', Theme_config.volume_osd.icon_color),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
resize = true,
|
||||
id = 'icon_role',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
id = "progressbar_container2",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(25),
|
||||
height = dpi(25),
|
||||
strategy = 'exact',
|
||||
},
|
||||
id = "progressbar_container",
|
||||
width = dpi(240),
|
||||
heigth = dpi(20),
|
||||
stragety = "max",
|
||||
widget = wibox.container.constraint
|
||||
{ -- Volume Bar
|
||||
{
|
||||
{
|
||||
id = 'progressbar',
|
||||
color = Theme_config.volume_osd.bar_bg_active,
|
||||
background_color = Theme_config.volume_osd.bar_bg,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
shape = gshape.rounded_rect,
|
||||
widget = wibox.widget.progressbar,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(250),
|
||||
height = dpi(5),
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{ -- Volume text
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'text_role',
|
||||
text = '0',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = "layout1",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
top = dpi(20),
|
||||
bottom = dpi(20),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "margin",
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
shape = Theme_config.volume_osd.shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
forced_width = dpi(300),
|
||||
forced_height = dpi(80),
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(12))
|
||||
end,
|
||||
ontop = true,
|
||||
stretch = false,
|
||||
visible = false,
|
||||
border_color = Theme_config.volume_osd.border_color,
|
||||
border_width = Theme_config.volume_osd.border_width,
|
||||
fg = Theme_config.volume_osd.fg,
|
||||
bg = Theme_config.volume_osd.bg,
|
||||
widget = wibox.container.background
|
||||
screen = 1,
|
||||
placement = function(c) aplacement.bottom(c, { margins = dpi(20) }) end,
|
||||
}
|
||||
|
||||
local volume_container = awful.popup {
|
||||
widget = ret.w,
|
||||
ontop = true,
|
||||
stretch = false,
|
||||
visible = false,
|
||||
screen = args.screen,
|
||||
placement = function(c) awful.placement.bottom_left(c, { margins = dpi(20) }) end,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(14))
|
||||
end
|
||||
}
|
||||
gtable.crush(w, osd)
|
||||
|
||||
local hide_volume_osd = gears.timer {
|
||||
w.timer = gtimer {
|
||||
timeout = 2,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
volume_container.visible = false
|
||||
end
|
||||
w.visible = false
|
||||
end,
|
||||
}
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"audio::get",
|
||||
function(muted, volume)
|
||||
if muted then
|
||||
ret.w:get_children_by_id("icon")[1]
|
||||
:set_image(gears.color.recolor_image(
|
||||
icondir .. "volume-mute" .. ".svg", Theme_config.volume_osd.icon_color))
|
||||
ret.w:get_children_by_id("progressbar1")[1].value = tonumber(0)
|
||||
else
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
ret.w:get_children_by_id("progressbar1")[1].value = tonumber(volume)
|
||||
local icon = icondir .. "volume"
|
||||
if volume < 1 then
|
||||
icon = icon .. "-mute"
|
||||
elseif volume >= 1 and volume < 34 then
|
||||
icon = icon .. "-low"
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. "-medium"
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. "-high"
|
||||
end
|
||||
ret.w:get_children_by_id("icon")[1]:set_image(gears.color.recolor_image(icon .. ".svg",
|
||||
Theme_config.volume_osd.icon_color))
|
||||
audio_helper:connect_signal('output::get', function(_, muted, volume)
|
||||
volume = tonumber(volume or 0)
|
||||
if muted then
|
||||
w.widget:get_children_by_id('icon_role')[1]:set_image(gcolor.recolor_image(icondir .. 'volume-mute' .. '.svg', Theme_config.volume_osd.icon_color))
|
||||
w.widget:get_children_by_id('progressbar')[1].value = 0
|
||||
else
|
||||
w.widget:get_children_by_id('progressbar')[1].value = volume
|
||||
local icon = icondir .. 'volume'
|
||||
if volume < 1 then
|
||||
icon = icon .. '-mute'
|
||||
elseif volume >= 1 and volume < 34 then
|
||||
icon = icon .. '-low'
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. '-medium'
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. '-high'
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"widget::volume_osd:rerun",
|
||||
function()
|
||||
if capi.mouse.screen == args.screen then
|
||||
volume_container.visible = true
|
||||
if hide_volume_osd.started then
|
||||
hide_volume_osd:again()
|
||||
else
|
||||
hide_volume_osd:start()
|
||||
end
|
||||
end
|
||||
w.widget:get_children_by_id('icon_role')[1]:set_image(gcolor.recolor_image(icon .. '.svg', Theme_config.volume_osd.icon_color))
|
||||
w.widget:get_children_by_id('text_role')[1].text = volume
|
||||
end
|
||||
)
|
||||
w:run()
|
||||
end)
|
||||
|
||||
return w
|
||||
end
|
||||
|
||||
function osd.mt:__call(...)
|
||||
return osd.new(...)
|
||||
end
|
||||
|
||||
return setmetatable(osd, osd.mt)
|
||||
return setmetatable(osd, { __call = function(_, ...) return osd.new(...) end })
|
||||
|
||||
@@ -3,23 +3,24 @@
|
||||
--------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require("awful.button")
|
||||
local awidget = require("awful.widget")
|
||||
local base = require("wibox.widget.base")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gcolor = require("gears").color
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local gtable = require("gears").table
|
||||
local lgi = require("lgi")
|
||||
local wibox = require("wibox")
|
||||
local abutton = require('awful.button')
|
||||
local awidget = require('awful.widget')
|
||||
local base = require('wibox.widget.base')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears').color
|
||||
local gfilesystem = require('gears').filesystem
|
||||
local gtable = require('gears').table
|
||||
local lgi = require('lgi')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Own libs
|
||||
local context_menu = require("src.modules.context_menu")
|
||||
local context_menu = require('src.modules.context_menu.init')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/bluetooth/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/bluetooth/'
|
||||
|
||||
local capi = {
|
||||
awesome = awesome
|
||||
awesome = awesome,
|
||||
}
|
||||
|
||||
local device = { mt = {} }
|
||||
@@ -33,7 +34,7 @@ function device:layout(_, width, height)
|
||||
end
|
||||
|
||||
function device:fit(context, width, height)
|
||||
local w, h = 0, 0
|
||||
local w, h = 0, 0 ---@type number|nil, number|nil
|
||||
if self._private.widget then
|
||||
w, h = base.fit_widget(self, context, self._private.widget, width, height)
|
||||
end
|
||||
@@ -48,29 +49,14 @@ end
|
||||
|
||||
--#endregion
|
||||
|
||||
local dbus_proxy = require('dbus_proxy')
|
||||
--- Connect to a device if not connected else disconnect
|
||||
function device:toggle_connect()
|
||||
if not self.device.Paired then
|
||||
self:toggle_pair()
|
||||
return
|
||||
end
|
||||
if not self.device.Connected then
|
||||
|
||||
--TODO: Implement device passcode support, I have no idea how to get the
|
||||
--TODO: Methods from Agent1 implemented
|
||||
--[[ self._private.AgentManager1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
path = "/org/bluez",
|
||||
interface = "org.bluez.AgentManager1"
|
||||
}
|
||||
|
||||
self._private.Agent1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
path = "/org/bluez",
|
||||
interface = "org.bluez.Agent1",
|
||||
}
|
||||
|
||||
self._private.AgentManager1:RegisterAgent(self._private.Agent1.object_path, "")
|
||||
self._private.AgentManager1:RequestDefaultAgent(self._private.Agent1.object_path) ]]
|
||||
|
||||
self.device:ConnectAsync()
|
||||
else
|
||||
self.device:DisconnectAsync()
|
||||
@@ -79,37 +65,52 @@ end
|
||||
|
||||
--- Pair to a device if not paired else unpair
|
||||
function device:toggle_pair()
|
||||
if self.device.Paired then
|
||||
if not self.device.Paired then
|
||||
self._private.AgentManager1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = 'org.bluez',
|
||||
path = '/org/bluez',
|
||||
interface = 'org.bluez.AgentManager1',
|
||||
}
|
||||
|
||||
self._private.Agent1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = 'org.bluez',
|
||||
path = '/org/bluez',
|
||||
interface = 'org.bluez.Agent1',
|
||||
}
|
||||
|
||||
self._private.AgentManager1:RegisterAgent(self._private.Agent1.object_path, 'KeyboardDisplay')
|
||||
self.device:PairAsync()
|
||||
else
|
||||
self.device:CancelPairingAsync()
|
||||
--Remove via adapter
|
||||
end
|
||||
end
|
||||
|
||||
--- Trust a device if not trusted else untrust
|
||||
function device:toggle_trusted()
|
||||
self.device:Set("org.bluez.Device1", "Trusted", lgi.GLib.Variant("b", not self.device.Trusted))
|
||||
self.device.Trusted = { signature = "b", value = not self.device.Trusted }
|
||||
self.device:Set('org.bluez.Device1', 'Trusted', lgi.GLib.Variant('b', not self.device.Trusted))
|
||||
self.device.Trusted = { signature = 'b', value = not self.device.Trusted }
|
||||
end
|
||||
|
||||
---Rename a device alias
|
||||
---@param newname string New name, if empty the device name will be reset
|
||||
---@return string name The new or old name depending if the string was empty or not
|
||||
function device:rename(newname)
|
||||
self.device:Set("org.bluez.Device1", "Alias", lgi.GLib.Variant("s", newname))
|
||||
self.device.Alias = { signature = "s", value = newname }
|
||||
return self.device:Get("org.bluez.Device1", "Alias")
|
||||
self.device:Set('org.bluez.Device1', 'Alias', lgi.GLib.Variant('s', newname))
|
||||
self.device.Alias = { signature = 's', value = newname }
|
||||
return self.device:Get('org.bluez.Device1', 'Alias')
|
||||
end
|
||||
|
||||
function device.new(args)
|
||||
args = args or {}
|
||||
|
||||
local icon = device.Icon or "bluetooth-on"
|
||||
local icon = device.Icon or 'bluetooth-on'
|
||||
|
||||
local inputbox = awidget.inputbox {
|
||||
text = args.device.Alias or args.device.Name,
|
||||
halign = "left",
|
||||
valign = "center",
|
||||
halign = 'left',
|
||||
valign = 'center',
|
||||
}
|
||||
|
||||
local ret = base.make_widget_from_value(wibox.widget {
|
||||
@@ -119,78 +120,80 @@ function device.new(args)
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(
|
||||
icondir .. icon .. ".svg", Theme_config.bluetooth_controller.icon_color),
|
||||
icondir .. icon .. '.svg', Theme_config.bluetooth_controller.icon_color),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
inputbox,
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = dpi(300),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{ -- Spacing
|
||||
forced_width = dpi(10),
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "con",
|
||||
id = 'con',
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
margins = dpi(2),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
shape = Theme_config.bluetooth_controller.icon_shape,
|
||||
bg = Theme_config.bluetooth_controller.con_button_color,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
margin = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.bluetooth_controller.device_bg,
|
||||
fg = Theme_config.bluetooth_controller.device_fg,
|
||||
border_color = Theme_config.bluetooth_controller.device_border_color,
|
||||
border_width = Theme_config.bluetooth_controller.device_border_width,
|
||||
id = "background",
|
||||
id = 'background',
|
||||
shape = Theme_config.bluetooth_controller.device_shape,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
})
|
||||
|
||||
assert(ret, 'Failed to create widget')
|
||||
|
||||
gtable.crush(ret, device, true)
|
||||
|
||||
ret.device = args.device or {}
|
||||
|
||||
-- Set the image of the connection button depending on the connection state
|
||||
ret:get_children_by_id("con")[1].image = gcolor.recolor_image(ret.device.Connected and icondir .. "link.svg" or
|
||||
icondir .. "link-off.svg",
|
||||
ret:get_children_by_id('con')[1].image = gcolor.recolor_image(ret.device.Connected and icondir .. 'link.svg' or
|
||||
icondir .. 'link-off.svg',
|
||||
Theme_config.bluetooth_controller.icon_color_dark)
|
||||
|
||||
local cm = context_menu {
|
||||
@@ -201,78 +204,82 @@ function device.new(args)
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'text_role',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
}, spacing = dpi(10),
|
||||
entries = {
|
||||
{ -- Connect/Disconnect a device
|
||||
name = ret.device.Connected and "Disconnect" or "Connect",
|
||||
icon = gcolor.recolor_image(ret.device.Connected and icondir .. "bluetooth-off.svg" or
|
||||
icondir .. "bluetooth-on.svg",
|
||||
name = ret.device.Connected and 'Disconnect' or 'Connect',
|
||||
icon = gcolor.recolor_image(ret.device.Connected and icondir .. 'bluetooth-off.svg' or
|
||||
icondir .. 'bluetooth-on.svg',
|
||||
Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
ret:toggle_connect()
|
||||
end,
|
||||
id = "connected"
|
||||
id = 'connected',
|
||||
},
|
||||
{ -- Pair/Unpair a device
|
||||
name = "Pair",
|
||||
icon = gcolor.recolor_image(ret.device.Paired and icondir .. "link-off.svg" or
|
||||
icondir .. "link.svg",
|
||||
name = 'Pair',
|
||||
icon = gcolor.recolor_image(ret.device.Paired and icondir .. 'link-off.svg' or
|
||||
icondir .. 'link.svg',
|
||||
Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
ret:toggle_pair()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{ -- Trust/Untrust a device
|
||||
name = ret.device.Trusted and "Untrust" or "Trust",
|
||||
icon = gcolor.recolor_image(ret.device.Trusted and icondir .. "untrusted.svg" or icondir .. "trusted.svg",
|
||||
name = ret.device.Trusted and 'Untrust' or 'Trust',
|
||||
icon = gcolor.recolor_image(ret.device.Trusted and icondir .. 'untrusted.svg' or icondir .. 'trusted.svg',
|
||||
Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
ret:toggle_trusted()
|
||||
end,
|
||||
id = "trusted"
|
||||
id = 'trusted',
|
||||
},
|
||||
{ -- Rename a device
|
||||
name = "Rename",
|
||||
icon = gcolor.recolor_image(icondir .. "edit.svg", Theme_config.bluetooth_controller.icon_color),
|
||||
name = 'Rename',
|
||||
icon = gcolor.recolor_image(icondir .. 'edit.svg', Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
inputbox:focus()
|
||||
inputbox:connect_signal("submit", function(text)
|
||||
inputbox:connect_signal('submit', function(text)
|
||||
text = text:get_text()
|
||||
inputbox.markup = ret:rename(text)
|
||||
end)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{ -- Remove a device
|
||||
name = "Remove",
|
||||
icon = gcolor.recolor_image(icondir .. "delete.svg", Theme_config.bluetooth_controller.icon_color),
|
||||
name = 'Remove',
|
||||
icon = gcolor.recolor_image(icondir .. 'delete.svg', Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
args.remove_callback(ret.device)
|
||||
end
|
||||
}
|
||||
}
|
||||
end,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cm:connect_signal('mouse::leave', function()
|
||||
cm.visible = false
|
||||
end)
|
||||
|
||||
ret:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
-- Toggle the connection state
|
||||
@@ -281,19 +288,19 @@ function device.new(args)
|
||||
abutton({}, 3, function()
|
||||
-- Show the context menu and update its entrie names
|
||||
for _, value in ipairs(cm.widget.children) do
|
||||
value.id = value.id or ""
|
||||
if value.id:match("connected") then
|
||||
value:get_children_by_id("text_role")[1].text = ret.device.Connected and "Disconnect" or "Connect"
|
||||
value:get_children_by_id("icon_role")[1].image = gcolor.recolor_image(ret.device.Connected and
|
||||
icondir .. "bluetooth-off.svg" or icondir .. "bluetooth-on.svg",
|
||||
value.id = value.id or ''
|
||||
if value.id:match('connected') then
|
||||
value:get_children_by_id('text_role')[1].text = ret.device.Connected and 'Disconnect' or 'Connect'
|
||||
value:get_children_by_id('icon_role')[1].image = gcolor.recolor_image(ret.device.Connected and
|
||||
icondir .. 'bluetooth-off.svg' or icondir .. 'bluetooth-on.svg',
|
||||
Theme_config.bluetooth_controller.icon_color)
|
||||
elseif value.id:match("trusted") then
|
||||
value:get_children_by_id("text_role")[1].text = ret.device.Trusted and "Untrust" or "Trust"
|
||||
value:get_children_by_id("icon_role")[1].image = gcolor.recolor_image(ret.device.Trusted and
|
||||
icondir .. "untrusted.svg" or icondir .. "trusted.svg", Theme_config.bluetooth_controller.icon_color)
|
||||
elseif value.id:match("paired") then
|
||||
value:get_children_by_id("icon_role")[1].image = gcolor.recolor_image(ret.device.Paired and
|
||||
icondir .. "link-off.svg" or icondir .. "link.svg", Theme_config.bluetooth_controller.icon_color)
|
||||
elseif value.id:match('trusted') then
|
||||
value:get_children_by_id('text_role')[1].text = ret.device.Trusted and 'Untrust' or 'Trust'
|
||||
value:get_children_by_id('icon_role')[1].image = gcolor.recolor_image(ret.device.Trusted and
|
||||
icondir .. 'untrusted.svg' or icondir .. 'trusted.svg', Theme_config.bluetooth_controller.icon_color)
|
||||
elseif value.id:match('paired') then
|
||||
value:get_children_by_id('icon_role')[1].image = gcolor.recolor_image(ret.device.Paired and
|
||||
icondir .. 'link-off.svg' or icondir .. 'link.svg', Theme_config.bluetooth_controller.icon_color)
|
||||
end
|
||||
end
|
||||
cm:toggle()
|
||||
@@ -301,13 +308,13 @@ function device.new(args)
|
||||
))
|
||||
|
||||
-- Update the updated device icon
|
||||
capi.awesome.connect_signal(ret.device.object_path .. "_updated", function(d)
|
||||
ret:get_children_by_id("con")[1].image = gcolor.recolor_image(d.Connected and icondir .. "link.svg" or
|
||||
icondir .. "link-off.svg",
|
||||
capi.awesome.connect_signal(ret.device.object_path .. '_updated', function(d)
|
||||
ret:get_children_by_id('con')[1].image = gcolor.recolor_image(d.Connected and icondir .. 'link.svg' or
|
||||
icondir .. 'link-off.svg',
|
||||
Theme_config.bluetooth_controller.icon_color_dark)
|
||||
end)
|
||||
|
||||
Hover_signal(ret)
|
||||
hover.bg_hover { widget = ret }
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -3,28 +3,29 @@
|
||||
--------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require("awful.button")
|
||||
local aspawn = require("awful.spawn")
|
||||
local base = require("wibox.widget.base")
|
||||
local dbus_proxy = require("src.lib.lua-dbus_proxy.src.dbus_proxy")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gcolor = require("gears").color
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local gshape = require("gears").shape
|
||||
local gtable = require("gears").table
|
||||
local gtimer = require("gears.timer")
|
||||
local lgi = require("lgi")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local abutton = require('awful.button')
|
||||
local aspawn = require('awful.spawn')
|
||||
local base = require('wibox.widget.base')
|
||||
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears').color
|
||||
local gfilesystem = require('gears').filesystem
|
||||
local gshape = require('gears').shape
|
||||
local gtable = require('gears').table
|
||||
local gtimer = require('gears.timer')
|
||||
local lgi = require('lgi')
|
||||
local naughty = require('naughty')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Third party libs
|
||||
local rubato = require("src.lib.rubato")
|
||||
local rubato = require('src.lib.rubato')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
-- Own libs
|
||||
local bt_device = require("src.modules.bluetooth.device")
|
||||
local dnd_widget = require("awful.widget.toggle_widget")
|
||||
local bt_device = require('src.modules.bluetooth.device')
|
||||
local dnd_widget = require('awful.widget.toggle_widget')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/bluetooth/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/bluetooth/'
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
@@ -61,13 +62,13 @@ end
|
||||
---Get the list of paired devices
|
||||
---@return table devices table of paired devices
|
||||
function bluetooth:get_paired_devices()
|
||||
return self:get_children_by_id("connected_device_list")[1].children
|
||||
return self:get_children_by_id('connected_device_list')[1].children
|
||||
end
|
||||
|
||||
---Get the list of discovered devices
|
||||
---@return table devices table of discovered devices
|
||||
function bluetooth:get_discovered_devices()
|
||||
return self:get_children_by_id("discovered_device_list")[1].children
|
||||
return self:get_children_by_id('discovered_device_list')[1].children
|
||||
end
|
||||
|
||||
--- Remove a device by first disconnecting it async then removing it
|
||||
@@ -81,8 +82,8 @@ end
|
||||
function bluetooth:add_device(device, object_path)
|
||||
|
||||
-- Get a reference to both lists
|
||||
local plist = self:get_children_by_id("connected_device_list")[1]
|
||||
local dlist = self:get_children_by_id("discovered_device_list")[1]
|
||||
local plist = self:get_children_by_id('connected_device_list')[1]
|
||||
local dlist = self:get_children_by_id('discovered_device_list')[1]
|
||||
|
||||
-- For the first list check if the device already exists and if its connection state changed
|
||||
-- if it changed then remove it from the current list and put it into the other one
|
||||
@@ -117,6 +118,7 @@ function bluetooth:add_device(device, object_path)
|
||||
self:remove_device_information(device)
|
||||
end,
|
||||
})
|
||||
self:emit_signal('device::added_connected')
|
||||
else
|
||||
dlist:add(bt_device {
|
||||
device = device,
|
||||
@@ -125,22 +127,25 @@ function bluetooth:add_device(device, object_path)
|
||||
self:remove_device_information(device)
|
||||
end,
|
||||
})
|
||||
self:emit_signal('device::added_discovered')
|
||||
end
|
||||
end
|
||||
|
||||
---Remove a device from any list
|
||||
---@param object_path string the object path of the device
|
||||
function bluetooth:remove_device(object_path)
|
||||
local plist = self:get_children_by_id("connected_device_list")[1]
|
||||
local dlist = self:get_children_by_id("discovered_device_list")[1]
|
||||
local plist = self:get_children_by_id('connected_device_list')[1]
|
||||
local dlist = self:get_children_by_id('discovered_device_list')[1]
|
||||
for _, d in ipairs(dlist.children) do
|
||||
if d.device.object_path == object_path then
|
||||
dlist:remove_widgets(d)
|
||||
self:emit_signal('device::removed_discovered')
|
||||
end
|
||||
end
|
||||
for _, d in ipairs(plist.children) do
|
||||
if d.device.object_path == object_path then
|
||||
if d.device.object_path == object_path and (not d.device.Paired) then
|
||||
plist:remove_widgets(d)
|
||||
self:emit_signal('device::removed_connected')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -159,42 +164,42 @@ end
|
||||
function bluetooth:toggle()
|
||||
local powered = self._private.Adapter1.Powered
|
||||
|
||||
self._private.Adapter1:Set("org.bluez.Adapter1", "Powered", lgi.GLib.Variant("b", not powered))
|
||||
self._private.Adapter1:Set('org.bluez.Adapter1', 'Powered', lgi.GLib.Variant('b', not powered))
|
||||
self._private.Adapter1.Powered = {
|
||||
signature = "b",
|
||||
value = not powered
|
||||
signature = 'b',
|
||||
value = not powered,
|
||||
}
|
||||
end
|
||||
|
||||
--- Open blueman-manager
|
||||
function bluetooth:open_settings()
|
||||
aspawn("blueman-manager")
|
||||
aspawn('blueman-manager')
|
||||
end
|
||||
|
||||
---Get a new device proxy and connect a PropertyChanged signal to it and
|
||||
---add the device to the list
|
||||
---@param object_path string the object path of the device
|
||||
function bluetooth:get_device_info(object_path)
|
||||
if (not object_path) or (not object_path:match("/org/bluez/hci0/dev")) then return end
|
||||
if (not object_path) or (not object_path:match('/org/bluez/hci0/dev')) then return end
|
||||
|
||||
-- New Device1 proxy
|
||||
local Device1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.bluez.Device1",
|
||||
path = object_path
|
||||
name = 'org.bluez',
|
||||
interface = 'org.bluez.Device1',
|
||||
path = object_path,
|
||||
}
|
||||
|
||||
-- New Properties proxy for the object_path
|
||||
local Device1Properties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
path = object_path
|
||||
name = 'org.bluez',
|
||||
interface = 'org.freedesktop.DBus.Properties',
|
||||
path = object_path,
|
||||
}
|
||||
|
||||
-- Just return if the Device1 has no name, this usually means random devices with just a mac address
|
||||
if (not Device1.Name) or (Device1.Name == "") then return end
|
||||
if (not Device1.Name) or (Device1.Name == '') then return end
|
||||
|
||||
-- For some reason it notifies twice or thrice
|
||||
local just_notified = false
|
||||
@@ -205,29 +210,29 @@ function bluetooth:get_device_info(object_path)
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
just_notified = false
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
-- Connect the PropertyChanged signal to update the device when a property changes and send a notification
|
||||
Device1Properties:connect_signal(function(_, _, changed_props)
|
||||
if changed_props["Connected"] ~= nil then
|
||||
if changed_props['Connected'] ~= nil then
|
||||
if not just_notified then
|
||||
naughty.notification({
|
||||
app_icon = icondir .. "bluetooth-on.svg",
|
||||
app_name = "Bluetooth",
|
||||
naughty.notification {
|
||||
app_icon = icondir .. 'bluetooth-on.svg',
|
||||
app_name = 'Bluetooth',
|
||||
title = Device1.Name,
|
||||
icon = gcolor.recolor_image(icondir .. Device1.Icon .. ".svg", Theme_config.bluetooth_controller.icon_color),
|
||||
icon = icondir .. Device1.Icon .. '.svg',
|
||||
timeout = 5,
|
||||
message = "Device " ..
|
||||
Device1.Name .. " is now " .. (changed_props["Connected"] and "connected" or "disconnected"),
|
||||
category = Device1.Connected and "device.added" or "device.removed",
|
||||
})
|
||||
message = 'Device ' ..
|
||||
Device1.Name .. ' is now ' .. (changed_props['Connected'] and 'connected' or 'disconnected'),
|
||||
category = Device1.Connected and 'device.added' or 'device.removed',
|
||||
}
|
||||
just_notified = true
|
||||
notify_timer:start()
|
||||
end
|
||||
end
|
||||
capi.awesome.emit_signal(object_path .. "_updated", Device1)
|
||||
end, "PropertiesChanged")
|
||||
capi.awesome.emit_signal(object_path .. '_updated', Device1)
|
||||
end, 'PropertiesChanged')
|
||||
|
||||
self:add_device(Device1, object_path)
|
||||
end
|
||||
@@ -236,13 +241,12 @@ end
|
||||
---@param powered boolean the powered state of the adapter
|
||||
local function send_state_notification(powered)
|
||||
naughty.notification {
|
||||
app_icon = gcolor.recolor_image(icondir .. "bluetooth-on.svg", Theme_config.bluetooth_controller.icon_color),
|
||||
app_name = "Bluetooth",
|
||||
title = "Bluetooth",
|
||||
message = powered and "Enabled" or "Disabled",
|
||||
icon = gcolor.recolor_image(powered and icondir .. "bluetooth-on.svg" or icondir .. "bluetooth-off.svg",
|
||||
Theme_config.bluetooth_controller.icon_color),
|
||||
category = powered and "device.added" or "device.removed",
|
||||
app_icon = icondir .. 'bluetooth-on.svg',
|
||||
app_name = 'Bluetooth',
|
||||
title = 'Bluetooth',
|
||||
message = powered and 'Enabled' or 'Disabled',
|
||||
icon = powered and icondir .. 'bluetooth-on.svg' or icondir .. 'bluetooth-off.svg',
|
||||
category = powered and 'device.added' or 'device.removed',
|
||||
}
|
||||
end
|
||||
|
||||
@@ -250,7 +254,7 @@ function bluetooth.new(args)
|
||||
args = args or {}
|
||||
|
||||
-- For some reason the first widget isn't read so the first container is a duplicate
|
||||
local ret = base.make_widget_from_value({
|
||||
local ret = base.make_widget_from_value {
|
||||
{
|
||||
{
|
||||
{
|
||||
@@ -258,128 +262,132 @@ function bluetooth.new(args)
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. "menu-down.svg",
|
||||
image = gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.bluetooth_controller.connected_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "connected_icon"
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'connected_icon',
|
||||
},
|
||||
{
|
||||
{
|
||||
text = "Paired Devices",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
text = 'Paired Devices',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
bg = Theme_config.bluetooth_controller.connected_bg,
|
||||
fg = Theme_config.bluetooth_controller.connected_fg,
|
||||
shape = Theme_config.bluetooth_controller.connected_shape,
|
||||
widget = wibox.container.background,
|
||||
id = "connected_bg"
|
||||
id = 'connected_bg',
|
||||
},
|
||||
id = "connected_margin",
|
||||
widget = wibox.container.margin
|
||||
id = 'connected_margin',
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
step = dpi(50),
|
||||
spacing = dpi(10),
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
scrollbar_width = 0,
|
||||
id = "connected_device_list"
|
||||
{
|
||||
step = dpi(50),
|
||||
spacing = dpi(10),
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
id = 'connected_device_list',
|
||||
},
|
||||
id = 'margin',
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "margin",
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
border_color = Theme_config.bluetooth_controller.con_device_border_color,
|
||||
border_width = Theme_config.bluetooth_controller.con_device_border_width,
|
||||
shape = Theme_config.bluetooth_controller.con_device_shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
border_color = Theme_config.bluetooth_controller.con_device_border_color,
|
||||
border_width = Theme_config.bluetooth_controller.con_device_border_width,
|
||||
shape = Theme_config.bluetooth_controller.con_device_shape,
|
||||
widget = wibox.container.background,
|
||||
forced_height = 0,
|
||||
id = "connected_list",
|
||||
widget = wibox.container.constraint,
|
||||
strategy = 'exact',
|
||||
height = 0,
|
||||
id = 'connected_list',
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. "menu-down.svg",
|
||||
image = gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.bluetooth_controller.discovered_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "discovered_icon",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'discovered_icon',
|
||||
},
|
||||
{
|
||||
{
|
||||
text = "Nearby Devices",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
text = 'Nearby Devices',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = "discovered_bg",
|
||||
id = 'discovered_bg',
|
||||
bg = Theme_config.bluetooth_controller.discovered_bg,
|
||||
fg = Theme_config.bluetooth_controller.discovered_fg,
|
||||
shape = Theme_config.bluetooth_controller.discovered_shape,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
id = "discovered_margin",
|
||||
id = 'discovered_margin',
|
||||
top = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "discovered_device_list",
|
||||
id = 'discovered_device_list',
|
||||
spacing = dpi(10),
|
||||
step = dpi(50),
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
border_color = Theme_config.bluetooth_controller.con_device_border_color,
|
||||
border_width = Theme_config.bluetooth_controller.con_device_border_width,
|
||||
shape = Theme_config.bluetooth_controller.con_device_shape,
|
||||
widget = wibox.container.background,
|
||||
forced_height = 0,
|
||||
id = "discovered_list",
|
||||
id = 'discovered_list',
|
||||
},
|
||||
{
|
||||
{ -- action buttons
|
||||
{
|
||||
dnd_widget {
|
||||
color = Theme_config.bluetooth_controller.power_bg,
|
||||
size = dpi(40)
|
||||
size = dpi(40),
|
||||
},
|
||||
id = "dnd",
|
||||
id = 'dnd',
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center"
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
nil,
|
||||
{ -- refresh
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. "refresh.svg",
|
||||
image = gcolor.recolor_image(icondir .. 'refresh.svg',
|
||||
Theme_config.bluetooth_controller.refresh_icon_color),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
@@ -387,28 +395,30 @@ function bluetooth.new(args)
|
||||
},
|
||||
shape = Theme_config.bluetooth_controller.refresh_shape,
|
||||
bg = Theme_config.bluetooth_controller.refresh_bg,
|
||||
id = "scan",
|
||||
widget = wibox.container.background
|
||||
id = 'scan',
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(10),
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
margins = dpi(15),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
margins = dpi(15),
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
}
|
||||
|
||||
assert(type(ret) == 'table', 'bluetooth_controller: ret is not a table')
|
||||
|
||||
-- Get a reference to the dnd button
|
||||
local dnd = ret:get_children_by_id("dnd")[1]:get_widget()
|
||||
local dnd = ret:get_children_by_id('dnd')[1]:get_widget()
|
||||
|
||||
-- Toggle bluetooth on or off
|
||||
dnd:connect_signal("dnd::toggle", function(enable)
|
||||
dnd:connect_signal('dnd::toggle', function()
|
||||
ret:toggle()
|
||||
end)
|
||||
|
||||
@@ -418,36 +428,38 @@ function bluetooth.new(args)
|
||||
-- Create a proxy for the freedesktop ObjectManager
|
||||
ret._private.ObjectManager = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.freedesktop.DBus.ObjectManager",
|
||||
path = "/"
|
||||
name = 'org.bluez',
|
||||
interface = 'org.freedesktop.DBus.ObjectManager',
|
||||
path = '/',
|
||||
}
|
||||
|
||||
-- Create a proxy for the bluez Adapter1 interface
|
||||
ret._private.Adapter1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.bluez.Adapter1",
|
||||
path = "/org/bluez/hci0"
|
||||
name = 'org.bluez',
|
||||
interface = 'org.bluez.Adapter1',
|
||||
path = '/org/bluez/hci0',
|
||||
}
|
||||
|
||||
if not ret._private.Adapter1.Powered then return end
|
||||
|
||||
-- Create a proxy for the bluez Adapter1 Properties interface
|
||||
ret._private.Adapter1Properties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
path = "/org/bluez/hci0"
|
||||
name = 'org.bluez',
|
||||
interface = 'org.freedesktop.DBus.Properties',
|
||||
path = '/org/bluez/hci0',
|
||||
}
|
||||
|
||||
-- Connect to the ObjectManager's InterfacesAdded signal
|
||||
ret._private.ObjectManager:connect_signal(function(_, interface)
|
||||
ret:get_device_info(interface)
|
||||
end, "InterfacesAdded")
|
||||
end, 'InterfacesAdded')
|
||||
|
||||
-- Connect to the ObjectManager's InterfacesRemoved signal
|
||||
ret._private.ObjectManager:connect_signal(function(_, interface)
|
||||
ret:remove_device(interface)
|
||||
end, "InterfacesRemoved")
|
||||
end, 'InterfacesRemoved')
|
||||
|
||||
-- Connect to the Adapter1's PropertiesChanged signal
|
||||
ret._private.Adapter1Properties:connect_signal(function(_, _, data)
|
||||
@@ -459,9 +471,9 @@ function bluetooth.new(args)
|
||||
else
|
||||
dnd:set_disabled()
|
||||
end
|
||||
ret:emit_signal("bluetooth::status", data.Powered)
|
||||
ret:emit_signal('bluetooth::status', data.Powered)
|
||||
end
|
||||
end, "PropertiesChanged")
|
||||
end, 'PropertiesChanged')
|
||||
|
||||
gtimer.delayed_call(function()
|
||||
for path, _ in pairs(ret._private.ObjectManager:GetManagedObjects()) do
|
||||
@@ -473,100 +485,160 @@ function bluetooth.new(args)
|
||||
else
|
||||
dnd:set_disabled()
|
||||
end
|
||||
ret:emit_signal("bluetooth::status", ret._private.Adapter1.Powered)
|
||||
ret:emit_signal('bluetooth::status', ret._private.Adapter1.Powered)
|
||||
send_state_notification(ret._private.Adapter1.Powered)
|
||||
end)
|
||||
--#endregion
|
||||
|
||||
--#region Dropdown logic
|
||||
local connected_margin = ret:get_children_by_id("connected_margin")[1]
|
||||
local connected_list = ret:get_children_by_id("connected_list")[1]
|
||||
local connected_icon = ret:get_children_by_id("connected_icon")[1]
|
||||
local connected_margin = ret:get_children_by_id('connected_margin')[1]
|
||||
local connected_list = ret:get_children_by_id('connected_list')[1]
|
||||
local connected_icon = ret:get_children_by_id('connected_icon')[1]
|
||||
|
||||
local connected_animation = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = connected_list.height,
|
||||
clamp_position = true,
|
||||
subscribed = function(v)
|
||||
connected_list.height = v
|
||||
end,
|
||||
}
|
||||
|
||||
ret:connect_signal('device::added_connected', function(device)
|
||||
if device.Connected then
|
||||
local size = (#ret:get_paired_devices() * 60)
|
||||
if size < 210 then
|
||||
connected_animation.target = dpi(size)
|
||||
|
||||
connected_margin:connect_signal(
|
||||
"button::press",
|
||||
function()
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = connected_list.forced_height,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
connected_list.forced_height = v
|
||||
end
|
||||
}
|
||||
if connected_list.forced_height == 0 then
|
||||
local size = (#ret:get_paired_devices() * 60)
|
||||
if size < 210 then
|
||||
rubato_timer.target = dpi(size)
|
||||
end
|
||||
if size > 0 then
|
||||
connected_margin.connected_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
connected_icon:set_image(gcolor.recolor_image(icondir .. "menu-up.svg",
|
||||
Theme_config.bluetooth_controller.connected_icon_color))
|
||||
end
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
connected_margin.connected_bg.shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 4)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
connected_icon:set_image(gcolor.recolor_image(icondir .. "menu-down.svg",
|
||||
|
||||
connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.bluetooth_controller.connected_icon_color))
|
||||
end
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
local discovered_margin = ret:get_children_by_id("discovered_margin")[1]
|
||||
local discovered_list = ret:get_children_by_id("discovered_list")[1]
|
||||
local discovered_bg = ret:get_children_by_id("discovered_bg")[1]
|
||||
local discovered_icon = ret:get_children_by_id("discovered_icon")[1]
|
||||
ret:connect_signal('device::removed_connected', function(device)
|
||||
local size = (#ret:get_paired_devices() * 60)
|
||||
if size < 210 then
|
||||
connected_animation.target = dpi(size)
|
||||
|
||||
discovered_margin:connect_signal(
|
||||
"button::press",
|
||||
function()
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = discovered_list.forced_height,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
discovered_list.forced_height = v
|
||||
end
|
||||
}
|
||||
connected_margin.connected_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
|
||||
if discovered_list.forced_height == 0 then
|
||||
local size = (#ret:get_discovered_devices() * 60)
|
||||
if size > 210 then
|
||||
size = 210
|
||||
connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.bluetooth_controller.connected_icon_color))
|
||||
end
|
||||
end)
|
||||
|
||||
connected_margin:connect_signal('button::press', function()
|
||||
if connected_list.height == 0 then
|
||||
local size = (#ret:get_paired_devices() * 60)
|
||||
if size < 210 then
|
||||
connected_animation.target = dpi(size)
|
||||
|
||||
connected_margin.connected_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
if size > 0 then
|
||||
rubato_timer.target = dpi(size)
|
||||
discovered_margin.discovered_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
discovered_icon:set_image(gcolor.recolor_image(icondir .. "menu-up.svg",
|
||||
Theme_config.bluetooth_controller.discovered_icon_color))
|
||||
|
||||
connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.bluetooth_controller.connected_icon_color))
|
||||
end
|
||||
else
|
||||
connected_animation.target = 0
|
||||
connected_margin.connected_bg.shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 4)
|
||||
end
|
||||
|
||||
connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.bluetooth_controller.connected_icon_color))
|
||||
end
|
||||
end)
|
||||
|
||||
local discovered_margin = ret:get_children_by_id('discovered_margin')[1]
|
||||
local discovered_list = ret:get_children_by_id('discovered_list')[1]
|
||||
local discovered_bg = ret:get_children_by_id('discovered_bg')[1]
|
||||
local discovered_icon = ret:get_children_by_id('discovered_icon')[1]
|
||||
|
||||
local discovered_animation = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = discovered_list.forced_height,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
discovered_list.forced_height = v
|
||||
end,
|
||||
}
|
||||
|
||||
ret:connect_signal('device::added_discovered', function(device)
|
||||
if not device.Connected then
|
||||
local size = (#ret:get_discovered_devices() * 60)
|
||||
if size > 210 then
|
||||
size = 210
|
||||
end
|
||||
if size > 0 then
|
||||
discovered_animation.target = dpi(size)
|
||||
discovered_margin.discovered_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
discovered_bg.shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 4)
|
||||
end
|
||||
discovered_icon:set_image(gcolor.recolor_image(icondir .. "menu-down.svg",
|
||||
discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.bluetooth_controller.discovered_icon_color))
|
||||
end
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
ret:connect_signal('device::removed_discovered', function(device)
|
||||
local size = (#ret:get_discovered_devices() * 60)
|
||||
if size > 210 then
|
||||
size = 210
|
||||
end
|
||||
if size > 0 then
|
||||
discovered_animation.target = dpi(size)
|
||||
discovered_margin.discovered_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.bluetooth_controller.discovered_icon_color))
|
||||
end
|
||||
end)
|
||||
|
||||
discovered_margin:connect_signal('button::press', function()
|
||||
if discovered_list.forced_height == 0 then
|
||||
local size = (#ret:get_discovered_devices() * 60)
|
||||
if size > 210 then
|
||||
size = 210
|
||||
end
|
||||
if size > 0 then
|
||||
discovered_animation.target = dpi(size)
|
||||
discovered_margin.discovered_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.bluetooth_controller.discovered_icon_color))
|
||||
end
|
||||
else
|
||||
discovered_animation.target = 0
|
||||
discovered_bg.shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 4)
|
||||
end
|
||||
discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.bluetooth_controller.discovered_icon_color))
|
||||
end
|
||||
end)
|
||||
--#endregion
|
||||
|
||||
-- Add buttons to the scan button
|
||||
ret:get_children_by_id("scan")[1]:buttons({
|
||||
ret:get_children_by_id('scan')[1]:buttons {
|
||||
abutton({}, 1, function()
|
||||
ret:scan()
|
||||
end)
|
||||
})
|
||||
end),
|
||||
}
|
||||
|
||||
Hover_signal(ret:get_children_by_id("scan")[1])
|
||||
hover.bg_hover { widget = ret:get_children_by_id('scan')[1] }
|
||||
hover.bg_hover { widget = connected_margin.connected_bg }
|
||||
hover.bg_hover { widget = discovered_bg }
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
---------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local aplacement = require("awful.placement")
|
||||
local apopup = require("awful.popup")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gcolor = require("gears.color")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local gtable = require("gears.table")
|
||||
local gshape = require("gears.shape")
|
||||
local gtimer = require("gears.timer")
|
||||
local wibox = require("wibox")
|
||||
local aplacement = require('awful.placement')
|
||||
local apopup = require('awful.popup')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gshape = require('gears.shape')
|
||||
local gtable = require('gears.table')
|
||||
local gtimer = require('gears.timer')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local backlight_helper = require("src.tools.helpers.backlight")
|
||||
local backlight_helper = require('src.tools.helpers.backlight')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
@@ -21,125 +21,119 @@ local capi = {
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/brightness/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/brightness/'
|
||||
|
||||
local brightness_osd = { mt = {} }
|
||||
|
||||
-- Hide the brightness_osd after 3 seconds
|
||||
function brightness_osd:hide()
|
||||
self.timer:stop(false)
|
||||
end
|
||||
|
||||
-- Rerun the timer
|
||||
function brightness_osd:rerun()
|
||||
function brightness_osd:run()
|
||||
self.visible = true
|
||||
self.timer:again(true)
|
||||
end
|
||||
|
||||
-- Show the brightness_osd for 3 seconds
|
||||
function brightness_osd:show()
|
||||
self.visible = true
|
||||
self.timer:start(true)
|
||||
if self.timer.started then
|
||||
self.timer:again()
|
||||
else
|
||||
self.timer:start()
|
||||
end
|
||||
end
|
||||
|
||||
function brightness_osd.new(args)
|
||||
args = args or {}
|
||||
|
||||
local osd = apopup {
|
||||
local w = apopup {
|
||||
widget = {
|
||||
{
|
||||
{
|
||||
{ -- Brightness Icon
|
||||
image = gcolor.recolor_image(icondir .. "brightness-high.svg", Theme_config.brightness_osd.icon_color),
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
resize = false,
|
||||
id = "icon",
|
||||
widget = wibox.widget.imagebox
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. 'volume-off.svg', Theme_config.brightness_ods.icon_color),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
resize = true,
|
||||
id = 'icon_role',
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(25),
|
||||
height = dpi(25),
|
||||
strategy = 'exact'
|
||||
},
|
||||
{ -- Brightness Bar
|
||||
{
|
||||
{
|
||||
id = "progressbar1",
|
||||
color = Theme_config.brightness_osd.bar_bg_active,
|
||||
background_color = Theme_config.brightness_osd.bar_bg,
|
||||
id = 'progressbar',
|
||||
color = Theme_config.brightness_ods.bar_bg_active,
|
||||
background_color = Theme_config.brightness_ods.bar_bg,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(6),
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_bar(cr, width, height, dpi(6))
|
||||
end,
|
||||
shape = gshape.rounded_rect,
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "progressbar_container2",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(250),
|
||||
height = dpi(5),
|
||||
},
|
||||
id = "progressbar_container",
|
||||
width = dpi(240),
|
||||
heigth = dpi(20),
|
||||
stragety = "max",
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.place
|
||||
},
|
||||
{ -- Brightness text
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'text_role',
|
||||
text = '0',
|
||||
valign = 'center',
|
||||
halign = 'center'
|
||||
},
|
||||
id = "layout1",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "margin",
|
||||
margins = dpi(10),
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
top = dpi(20),
|
||||
bottom = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
forced_width = dpi(300),
|
||||
forced_height = dpi(80),
|
||||
border_color = Theme_config.brightness_osd.border_color,
|
||||
border_width = Theme_config.brightness_osd.border_width,
|
||||
fg = Theme_config.brightness_osd.fg,
|
||||
bg = Theme_config.brightness_osd.bg,
|
||||
shape = Theme_config.brightness_ods.shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
ontop = true,
|
||||
stretch = false,
|
||||
visible = false,
|
||||
screen = args.screen,
|
||||
placement = function(c) aplacement.bottom_left(c, { margins = dpi(20) }) end,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(14))
|
||||
border_color = Theme_config.brightness_ods.border_color,
|
||||
border_width = Theme_config.brightness_ods.border_width,
|
||||
fg = Theme_config.brightness_ods.fg,
|
||||
bg = Theme_config.brightness_ods.bg,
|
||||
screen = 1,
|
||||
placement = function(c) aplacement.bottom(c, { margins = dpi(20) }) end,
|
||||
}
|
||||
|
||||
gtable.crush(w, brightness_osd, true)
|
||||
|
||||
w.timer = gtimer {
|
||||
timeout = 2,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
w.visible = false
|
||||
end
|
||||
}
|
||||
|
||||
gtable.crush(osd, brightness_osd, true)
|
||||
backlight_helper:connect_signal('brightness_changed', function()
|
||||
backlight_helper:brightness_get_async(function(brightness)
|
||||
brightness = brightness / (backlight_helper.brightness_max or 24000) * 100
|
||||
w.widget:get_children_by_id('progressbar')[1].value = brightness
|
||||
|
||||
-- Called when the brightness changes, updates the brightness osd and icon
|
||||
capi.awesome.connect_signal("brightness::changed", function(brightness)
|
||||
if not capi.mouse.screen == args.screen then return end
|
||||
assert(type(brightness) == "number", "brightness must be a number")
|
||||
local icon = icondir .. 'brightness'
|
||||
if brightness >= 0 and brightness < 34 then
|
||||
icon = icon .. '-low.svg'
|
||||
elseif brightness >= 34 and brightness < 67 then
|
||||
icon = icon .. '-medium.svg'
|
||||
elseif brightness >= 67 then
|
||||
icon = icon .. '-high.svg'
|
||||
end
|
||||
|
||||
brightness = (brightness - 0) / ((backlight_helper.brightness_max or 24000) - 0) * 100
|
||||
osd.widget:get_children_by_id("progressbar1")[1].value = brightness
|
||||
|
||||
local icon = icondir .. "brightness"
|
||||
if brightness >= 0 and brightness < 34 then
|
||||
icon = icon .. "-low.svg"
|
||||
elseif brightness >= 34 and brightness < 67 then
|
||||
icon = icon .. "-medium.svg"
|
||||
elseif brightness >= 67 then
|
||||
icon = icon .. "-high.svg"
|
||||
end
|
||||
|
||||
osd:rerun(true)
|
||||
osd.widget:get_children_by_id("icon")[1]:set_image(gcolor.recolor_image(icon,
|
||||
Theme_config.brightness_osd.icon_color))
|
||||
w.widget:get_children_by_id('icon')[1]:set_image(gcolor.recolor_image(icon, Theme_config.brightness_osd.icon_color))
|
||||
w.widget:get_children_by_id('text_role')[1].text = brightness
|
||||
w:run()
|
||||
end)
|
||||
end)
|
||||
|
||||
-- osd timer
|
||||
osd.timer = gtimer {
|
||||
timeout = 3,
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
osd.visible = false
|
||||
end
|
||||
}
|
||||
return w
|
||||
end
|
||||
|
||||
function brightness_osd.mt:__call(...)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,23 +1,21 @@
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears.table")
|
||||
local gobject = require("gears.object")
|
||||
local gshape = require("gears.shape")
|
||||
local gcolor = require("gears.color")
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local wibox = require("wibox")
|
||||
local base = require("wibox.widget.base")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gtable = require('gears.table')
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears').filesystem
|
||||
local wibox = require('wibox')
|
||||
local base = require('wibox.widget.base')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
local ical_parser = require("src.tools.ical_parser")()
|
||||
local task_info = require("src.modules.calendar.task_info")
|
||||
local ical_parser = require('src.tools.ical_parser')()
|
||||
local task_info = require('src.modules.calendar.task_info')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/calendar/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/calendar/'
|
||||
|
||||
local calendar = { mt = {} }
|
||||
calendar.tasks = {}
|
||||
@@ -27,36 +25,36 @@ calendar._private = {}
|
||||
|
||||
-- Month lookup table
|
||||
calendar._private.months = {
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December"
|
||||
'January',
|
||||
'February',
|
||||
'March',
|
||||
'April',
|
||||
'May',
|
||||
'June',
|
||||
'July',
|
||||
'August',
|
||||
'September',
|
||||
'October',
|
||||
'November',
|
||||
'December',
|
||||
}
|
||||
|
||||
-- Weeks shortname lookup table
|
||||
calendar._private.weeks = {
|
||||
"Mon",
|
||||
"Tue",
|
||||
"Wed",
|
||||
"Thu",
|
||||
"Fri",
|
||||
"Sat",
|
||||
"Sun"
|
||||
'Mon',
|
||||
'Tue',
|
||||
'Wed',
|
||||
'Thu',
|
||||
'Fri',
|
||||
'Sat',
|
||||
'Sun',
|
||||
}
|
||||
|
||||
--- A date table to keep track of the needed date
|
||||
calendar.date = {
|
||||
day = tonumber(os.date("%d")) or 1,
|
||||
month = tonumber(os.date("%m")) or 1,
|
||||
year = tonumber(os.date("%Y")) or 1970
|
||||
day = tonumber(os.date('%d')) or 1,
|
||||
month = tonumber(os.date('%m')) or 1,
|
||||
year = tonumber(os.date('%Y')) or 1970,
|
||||
}
|
||||
|
||||
--#region base widget functions
|
||||
@@ -67,7 +65,7 @@ function calendar:layout(_, width, height)
|
||||
end
|
||||
|
||||
function calendar:fit(context, width, height)
|
||||
local w, h = 0, 0
|
||||
local w, h = 0, 0 ---@type number|nil, number|nil
|
||||
if self._private.widget then
|
||||
w, h = base.fit_widget(self, context, self._private.widget, width, height)
|
||||
end
|
||||
@@ -102,7 +100,7 @@ function calendar:get_last_day_in_month(month, year)
|
||||
[9] = 30,
|
||||
[10] = 31,
|
||||
[11] = 30,
|
||||
[12] = 31
|
||||
[12] = 31,
|
||||
}
|
||||
|
||||
if (month == 2) and (math.floor(year % 4) == 0) then
|
||||
@@ -136,10 +134,10 @@ function calendar:weekday_for_day(day, month, year)
|
||||
end
|
||||
|
||||
-- Forgot what the algorithm was called
|
||||
local w = ((day + math.floor(2.6 * month - 0.2) - 2 * tonumber(tostring(year):match("([0-9]+)[0-9][0-9]")) +
|
||||
tonumber(tostring(year):match("[0-9][0-9]([0-9]+)")) +
|
||||
math.floor(tonumber(tostring(year):match("[0-9][0-9]([0-9]+)")) / 4) +
|
||||
math.floor(tonumber(tostring(year):match("([0-9]+)[0-9][0-9]")) / 4)) % 7)
|
||||
local w = ((day + math.floor(2.6 * month - 0.2) - 2 * tonumber(tostring(year):match('([0-9]+)[0-9][0-9]')) +
|
||||
tonumber(tostring(year):match('[0-9][0-9]([0-9]+)')) +
|
||||
math.floor(tonumber(tostring(year):match('[0-9][0-9]([0-9]+)')) / 4) +
|
||||
math.floor(tonumber(tostring(year):match('([0-9]+)[0-9][0-9]')) / 4)) % 7)
|
||||
|
||||
-- If the week should start on monday, sunday is default. Since the function returns 0 - 6, we have to add 1 for lua's tables
|
||||
if w == 0 then w = 7 end
|
||||
@@ -181,7 +179,7 @@ function calendar:get_tasks()
|
||||
day = start_date.d,
|
||||
hour = start_date.hour or 0,
|
||||
min = start_date.min or 0,
|
||||
sec = start_date.sec or 0
|
||||
sec = start_date.sec or 0,
|
||||
},
|
||||
date_end = {
|
||||
year = end_date.y,
|
||||
@@ -189,7 +187,7 @@ function calendar:get_tasks()
|
||||
day = end_date.d,
|
||||
hour = end_date.hour or 0,
|
||||
min = end_date.min or 0,
|
||||
sec = end_date.sec or 0
|
||||
sec = end_date.sec or 0,
|
||||
},
|
||||
summary = sum,
|
||||
location = loc,
|
||||
@@ -219,12 +217,12 @@ function calendar:get_tasks()
|
||||
day = start_time.day,
|
||||
hour = start_time.hour,
|
||||
min = start_time.min,
|
||||
sec = start_time.sec
|
||||
sec = start_time.sec,
|
||||
}
|
||||
end
|
||||
-- Get repeat cases
|
||||
if event.RRULE then
|
||||
if event.RRULE.FREQ == "DAILY" then
|
||||
if event.RRULE.FREQ == 'DAILY' then
|
||||
local year_counter, month_counter, day_counter = start_time.year, start_time.month,
|
||||
start_time.day
|
||||
while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or
|
||||
@@ -235,14 +233,14 @@ function calendar:get_tasks()
|
||||
d = day_counter,
|
||||
hour = start_time.hour,
|
||||
min = start_time.min,
|
||||
sec = start_time.sec
|
||||
sec = start_time.sec,
|
||||
}, {
|
||||
y = year_counter,
|
||||
m = month_counter,
|
||||
d = day_counter,
|
||||
hour = end_time.hour,
|
||||
min = end_time.min,
|
||||
sec = end_time.sec
|
||||
sec = end_time.sec,
|
||||
}, event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
|
||||
|
||||
day_counter = day_counter + 1
|
||||
@@ -255,14 +253,14 @@ function calendar:get_tasks()
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif event.RRULE.FREQ == "WEEKLY" then
|
||||
elseif event.RRULE.FREQ == 'WEEKLY' then
|
||||
local year_counter, month_counter, day_counter = start_time.year, start_time.month,
|
||||
start_time.day
|
||||
while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or
|
||||
(day_counter <= event.RRULE.UNTIL.day) do
|
||||
task_factory({ y = year_counter, m = month_counter, d = day_counter, hour = start_time.hour,
|
||||
min = start_time.min, sec = start_time.sec }, { y = year_counter, m = month_counter,
|
||||
d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec },
|
||||
min = start_time.min, sec = start_time.sec, }, { y = year_counter, m = month_counter,
|
||||
d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec, },
|
||||
event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
|
||||
day_counter = day_counter + 7
|
||||
local month_length = calendar:get_last_day_in_month(month_counter, year_counter)
|
||||
@@ -275,14 +273,14 @@ function calendar:get_tasks()
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif event.RRULE.FREQ == "MONTHLY" then
|
||||
elseif event.RRULE.FREQ == 'MONTHLY' then
|
||||
local year_counter, month_counter, day_counter = start_time.year, start_time.month,
|
||||
start_time.day
|
||||
while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or
|
||||
(day_counter <= event.RRULE.UNTIL.day) do
|
||||
task_factory({ y = year_counter, m = month_counter, d = day_counter, hour = start_time.hour,
|
||||
min = start_time.min, sec = start_time.sec }, { y = year_counter, m = month_counter,
|
||||
d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec },
|
||||
min = start_time.min, sec = start_time.sec, }, { y = year_counter, m = month_counter,
|
||||
d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec, },
|
||||
event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
|
||||
month_counter = month_counter + 1
|
||||
if month_counter > 12 then
|
||||
@@ -290,27 +288,27 @@ function calendar:get_tasks()
|
||||
year_counter = year_counter + 1
|
||||
end
|
||||
end
|
||||
elseif event.RRULE.FREQ == "YEARLY" then
|
||||
elseif event.RRULE.FREQ == 'YEARLY' then
|
||||
end_time = event.RRULE.UNTIL
|
||||
if not event.RRULE.UNTIL then
|
||||
end_time = {
|
||||
year = start_time.year + 1000,
|
||||
month = start_time.month,
|
||||
day = start_time.day
|
||||
day = start_time.day,
|
||||
}
|
||||
end
|
||||
for i = start_time.year, end_time.year, 1 do
|
||||
task_factory({ y = i, m = start_time.month, d = start_time.day, hour = start_time.hour,
|
||||
min = start_time.min, sec = start_time.sec }, { y = i, m = end_time.month, d = end_time.day,
|
||||
hour = end_time.hour, min = end_time.min, sec = end_time.sec }, event.SUMMARY,
|
||||
min = start_time.min, sec = start_time.sec, }, { y = i, m = end_time.month, d = end_time.day,
|
||||
hour = end_time.hour, min = end_time.min, sec = end_time.sec, }, event.SUMMARY,
|
||||
event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
|
||||
end
|
||||
end
|
||||
-- If RRULE is empty we just add a single day event
|
||||
else
|
||||
task_factory({ y = start_time.year, m = start_time.month, d = start_time.day, hour = start_time.hour,
|
||||
min = start_time.min, sec = start_time.sec }, { y = end_time.year, m = end_time.month,
|
||||
d = end_time.day, hour = end_time.hour, min = end_time.min, sec = end_time.sec },
|
||||
min = start_time.min, sec = start_time.sec, }, { y = end_time.year, m = end_time.month,
|
||||
d = end_time.day, hour = end_time.hour, min = end_time.min, sec = end_time.sec, },
|
||||
event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
|
||||
end
|
||||
if event.VALARM then
|
||||
@@ -323,7 +321,7 @@ function calendar:get_tasks()
|
||||
table.insert(self.tasks, tasks)
|
||||
table.insert(self.calendars, {
|
||||
tasks = self.tasks,
|
||||
color = cal.color
|
||||
color = cal.color,
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -344,19 +342,19 @@ function calendar:create_calendar_weeks_widget()
|
||||
{
|
||||
{
|
||||
text = i,
|
||||
id = "num",
|
||||
align = "center",
|
||||
valign = "top",
|
||||
id = 'num',
|
||||
align = 'center',
|
||||
valign = 'top',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
id = "background",
|
||||
id = 'background',
|
||||
fg = Theme_config.calendar.day.fg_unfocus,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
height = dpi(120),
|
||||
width = dpi(40),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.constraint,
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -369,8 +367,8 @@ function calendar:create_weekdays_widget()
|
||||
self._private.weekdays:add(wibox.widget {
|
||||
{
|
||||
text = self._private.weeks[i],
|
||||
align = "center",
|
||||
valign = "center",
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
bg = Theme_config.calendar.weekdays.bg,
|
||||
@@ -404,10 +402,10 @@ function calendar:create_calendar_widget()
|
||||
local function get_tasks_for_day(day, month, year)
|
||||
if not self.tasks or #self.tasks == 0 then return end
|
||||
local tasks_layout = {
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
step = dpi(50),
|
||||
spacing = dpi(2)
|
||||
spacing = dpi(2),
|
||||
}
|
||||
|
||||
local function task_factory(task, bg)
|
||||
@@ -415,19 +413,19 @@ function calendar:create_calendar_widget()
|
||||
{
|
||||
{
|
||||
text = task.summary,
|
||||
align = "left",
|
||||
halign = "center",
|
||||
font = "JetBrainsMono Nerd Font, bold 10",
|
||||
widget = wibox.widget.textbox
|
||||
align = 'left',
|
||||
halign = 'center',
|
||||
font = 'JetBrainsMono Nerd Font, bold 10',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
margins = dpi(2),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
fg = Theme_config.calendar.task.fg,
|
||||
bg = bg,
|
||||
shape = Theme_config.calendar.task.shape,
|
||||
forced_height = dpi(20),
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -442,7 +440,7 @@ function calendar:create_calendar_widget()
|
||||
(
|
||||
task.date_start.year == self.date.year and task.date_start.month == self.date.month and
|
||||
task.date_start.day < self.date.day) then
|
||||
tw = task_factory(task, cal.color .. "55")
|
||||
tw = task_factory(task, cal.color .. '55')
|
||||
else
|
||||
tw = task_factory(task, cal.color)
|
||||
end
|
||||
@@ -466,10 +464,10 @@ function calendar:create_calendar_widget()
|
||||
widget = ti,
|
||||
ontop = true,
|
||||
visible = false,
|
||||
bg = "#00000000",
|
||||
bg = '#00000000',
|
||||
x = capi.mouse.coords().x,
|
||||
y = capi.mouse.coords().y,
|
||||
screen = self.screen
|
||||
screen = capi.mouse.screen,
|
||||
}
|
||||
|
||||
tw:buttons(
|
||||
@@ -482,11 +480,11 @@ function calendar:create_calendar_widget()
|
||||
)
|
||||
)
|
||||
|
||||
tw:connect_signal("mouse::leave", function()
|
||||
tw:connect_signal('mouse::leave', function()
|
||||
task_popup.visible = false
|
||||
end)
|
||||
|
||||
Hover_signal(tw)
|
||||
hover.bg_hover { widget = tw }
|
||||
|
||||
table.insert(tasks_layout, tw)
|
||||
end
|
||||
@@ -514,8 +512,8 @@ function calendar:create_calendar_widget()
|
||||
local bg = Theme_config.calendar.day.bg_unfocus
|
||||
local fg = Theme_config.calendar.day.fg_unfocus
|
||||
|
||||
local y = tonumber(os.date("%Y"))
|
||||
local m = tonumber(os.date("%m"))
|
||||
local y = tonumber(os.date('%Y'))
|
||||
local m = tonumber(os.date('%m'))
|
||||
|
||||
if (i == self.date.day) and (m == last_month) and (y == year) then
|
||||
bg = Theme_config.calendar.day.bg_focus
|
||||
@@ -531,39 +529,39 @@ function calendar:create_calendar_widget()
|
||||
{
|
||||
{ -- Day
|
||||
widget = wibox.widget.textbox,
|
||||
align = "center",
|
||||
valign = "center",
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
text = math.floor(i),
|
||||
id = "day_text",
|
||||
id = 'day_text',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(2),
|
||||
},
|
||||
id = "day_bg",
|
||||
id = 'day_bg',
|
||||
widget = wibox.container.background,
|
||||
bg = bg,
|
||||
shape = Theme_config.calendar.day.shape,
|
||||
fg = fg,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
{
|
||||
get_tasks_for_day(math.floor(i), last_month, year),
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(4),
|
||||
id = "day_tasks",
|
||||
id = 'day_tasks',
|
||||
},
|
||||
id = "tasks",
|
||||
id = 'tasks',
|
||||
spacing = dpi(4),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
id = "day_bg",
|
||||
id = 'day_bg',
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(4)
|
||||
top = dpi(4),
|
||||
},
|
||||
id = "background",
|
||||
id = 'background',
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.calendar.day.bg_unfocus,
|
||||
fg = Theme_config.calendar.day.fg_unfocus,
|
||||
@@ -571,11 +569,11 @@ function calendar:create_calendar_widget()
|
||||
border_width = Theme_config.calendar.day.border_width,
|
||||
shape = Theme_config.calendar.day.shape,
|
||||
},
|
||||
id = "day",
|
||||
id = 'day',
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(100),
|
||||
height = dpi(120),
|
||||
strategy = "exact"
|
||||
strategy = 'exact',
|
||||
}
|
||||
|
||||
self._private.calendar_matrix:add_widget_at(day, 1, column)
|
||||
@@ -592,8 +590,8 @@ function calendar:create_calendar_widget()
|
||||
local bg = Theme_config.calendar.day.bg
|
||||
local fg = Theme_config.calendar.day.fg
|
||||
|
||||
local m = tonumber(os.date("%m"))
|
||||
local y = tonumber(os.date("%Y"))
|
||||
local m = tonumber(os.date('%m'))
|
||||
local y = tonumber(os.date('%Y'))
|
||||
if (i == self.date.day) and (m == self.date.month) and (y == self.date.year) then
|
||||
bg = Theme_config.calendar.day.bg_focus
|
||||
fg = Theme_config.calendar.day.fg_focus
|
||||
@@ -608,37 +606,37 @@ function calendar:create_calendar_widget()
|
||||
{
|
||||
{ -- Day
|
||||
widget = wibox.widget.textbox,
|
||||
align = "center",
|
||||
valign = "center",
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
text = math.floor(i),
|
||||
id = "day_text",
|
||||
id = 'day_text',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(2),
|
||||
},
|
||||
id = "day_bg",
|
||||
id = 'day_bg',
|
||||
widget = wibox.container.background,
|
||||
bg = bg,
|
||||
shape = Theme_config.calendar.day.shape,
|
||||
fg = fg,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
{
|
||||
get_tasks_for_day(math.floor(i), self.date.month, self.date.year),
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(4)
|
||||
margins = dpi(4),
|
||||
},
|
||||
id = "tasks",
|
||||
id = 'tasks',
|
||||
spacing = dpi(4),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(4)
|
||||
top = dpi(4),
|
||||
},
|
||||
id = "background",
|
||||
id = 'background',
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.calendar.day.bg,
|
||||
fg = Theme_config.calendar.day.fg,
|
||||
@@ -649,7 +647,7 @@ function calendar:create_calendar_widget()
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(100),
|
||||
height = dpi(120),
|
||||
strategy = "exact"
|
||||
strategy = 'exact',
|
||||
}
|
||||
|
||||
self._private.calendar_matrix:add_widget_at(day, row, col)
|
||||
@@ -674,8 +672,8 @@ function calendar:create_calendar_widget()
|
||||
local bg = Theme_config.calendar.day.bg_unfocus
|
||||
local fg = Theme_config.calendar.day.fg_unfocus
|
||||
|
||||
local m = tonumber(os.date("%m"))
|
||||
local y = tonumber(os.date("%Y"))
|
||||
local m = tonumber(os.date('%m'))
|
||||
local y = tonumber(os.date('%Y'))
|
||||
if (i == self.date.day) and (m == next_month) and (y == year) then
|
||||
bg = Theme_config.calendar.day.bg_focus
|
||||
fg = Theme_config.calendar.day.fg_focus
|
||||
@@ -689,37 +687,37 @@ function calendar:create_calendar_widget()
|
||||
{
|
||||
{ -- Day
|
||||
widget = wibox.widget.textbox,
|
||||
align = "center",
|
||||
valign = "center",
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
text = math.floor(i),
|
||||
id = "day_text",
|
||||
id = 'day_text',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(2),
|
||||
},
|
||||
id = "day_bg",
|
||||
id = 'day_bg',
|
||||
widget = wibox.container.background,
|
||||
bg = bg,
|
||||
shape = Theme_config.calendar.day.shape,
|
||||
fg = fg,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
{
|
||||
get_tasks_for_day(math.floor(i), next_month, year),
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(4)
|
||||
margins = dpi(4),
|
||||
},
|
||||
id = "tasks",
|
||||
id = 'tasks',
|
||||
spacing = dpi(4),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(4)
|
||||
top = dpi(4),
|
||||
},
|
||||
id = "background",
|
||||
id = 'background',
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.calendar.day.bg_unfocus,
|
||||
fg = Theme_config.calendar.day.fg_unfocus,
|
||||
@@ -730,7 +728,7 @@ function calendar:create_calendar_widget()
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(100),
|
||||
height = dpi(120),
|
||||
strategy = "exact"
|
||||
strategy = 'exact',
|
||||
}
|
||||
self._private.calendar_matrix:add_widget_at(day, months_t[self.date.month].weeks,
|
||||
months_t[self.date.month].last_day + i)
|
||||
@@ -754,44 +752,44 @@ function calendar.new(args)
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. "add_ical.svg", Theme_config.calendar.add_ical.fg_focus),
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
image = gcolor.recolor_image(icondir .. 'add_ical.svg', Theme_config.calendar.add_ical.fg_focus),
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
id = "add_ical",
|
||||
id = 'add_ical',
|
||||
shape = Theme_config.calendar.add_ical.shape,
|
||||
bg = Theme_config.calendar.add_ical.bg,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(4)
|
||||
margins = dpi(4),
|
||||
},
|
||||
{ -- New task button
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. "add_task.svg", Theme_config.calendar.add_task.fg),
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
image = gcolor.recolor_image(icondir .. 'add_task.svg', Theme_config.calendar.add_task.fg),
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
id = "add_task",
|
||||
id = 'add_task',
|
||||
shape = Theme_config.calendar.add_task.shape,
|
||||
bg = Theme_config.calendar.add_task.bg,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(4)
|
||||
margins = dpi(4),
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
height = dpi(75)
|
||||
strategy = 'exact',
|
||||
height = dpi(75),
|
||||
},
|
||||
ret._private.calendar_weeks_widget,
|
||||
id = "weekdaysnum",
|
||||
layout = wibox.layout.fixed.vertical
|
||||
id = 'weekdaysnum',
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
{
|
||||
{
|
||||
@@ -800,88 +798,88 @@ function calendar.new(args)
|
||||
{ -- Prev arrow
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
image = icondir .. "chevron-left.svg",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "prev_month",
|
||||
image = icondir .. 'chevron-left.svg',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'prev_month',
|
||||
},
|
||||
{
|
||||
{ -- Month
|
||||
widget = wibox.widget.textbox,
|
||||
text = ret._private.months[ret.date.month],
|
||||
id = "month",
|
||||
valign = "center",
|
||||
align = "center"
|
||||
id = 'month',
|
||||
valign = 'center',
|
||||
align = 'center',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
width = dpi(150)
|
||||
strategy = 'exact',
|
||||
width = dpi(150),
|
||||
},
|
||||
{ -- Next year arrow
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
image = icondir .. "chevron-right.svg",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "next_month",
|
||||
image = icondir .. 'chevron-right.svg',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'next_month',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
nil,
|
||||
{ -- Year year switcher
|
||||
{ -- Prev arrow
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
image = icondir .. "chevron-left.svg",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "prev_year"
|
||||
image = icondir .. 'chevron-left.svg',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'prev_year',
|
||||
},
|
||||
{
|
||||
{ -- Year
|
||||
widget = wibox.widget.textbox,
|
||||
text = calendar.date.year,
|
||||
id = "year",
|
||||
valign = "center",
|
||||
align = "center"
|
||||
id = 'year',
|
||||
valign = 'center',
|
||||
align = 'center',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
width = dpi(150)
|
||||
strategy = 'exact',
|
||||
width = dpi(150),
|
||||
},
|
||||
{ -- Next year arrow
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
image = icondir .. "chevron-right.svg",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "next_year"
|
||||
image = icondir .. 'chevron-right.svg',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'next_year',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(40),
|
||||
strategy = "exact"
|
||||
strategy = 'exact',
|
||||
},
|
||||
{ -- Weekdays
|
||||
ret._private.weekdays,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
ret._private.calendar_matrix,
|
||||
id = "calendar",
|
||||
id = 'calendar',
|
||||
spacing = dpi(5),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
id = "lay1",
|
||||
id = 'lay1',
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.calendar.bg,
|
||||
border_color = Theme_config.calendar.border_color,
|
||||
border_width = Theme_config.calendar.border_width,
|
||||
border_strategy = "inner",
|
||||
border_strategy = 'inner',
|
||||
fg = Theme_config.calendar.fg,
|
||||
shape = Theme_config.calendar.shape,
|
||||
})
|
||||
@@ -893,13 +891,13 @@ function calendar.new(args)
|
||||
ret:create_weekdays_widget()
|
||||
ret:create_calendar_weeks_widget()
|
||||
|
||||
ret:get_widget():get_children_by_id("add_ical")[1]:buttons(gtable.join(
|
||||
ret:get_widget():get_children_by_id('add_ical')[1]:buttons(gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"zenity --file-selection --title='Select an ICalendar file' --file-filter='iCalendar File | *.ics'",
|
||||
function(path_to_file)
|
||||
path_to_file = string.gsub(path_to_file, "\n", "")
|
||||
if (not path_to_file) or (path_to_file == "") then return end
|
||||
path_to_file = string.gsub(path_to_file, '\n', '')
|
||||
if (not path_to_file) or (path_to_file == '') then return end
|
||||
ical_parser:add_calendar(path_to_file)
|
||||
ret:get_tasks()
|
||||
ret:create_calendar_widget()
|
||||
@@ -908,7 +906,7 @@ function calendar.new(args)
|
||||
end)
|
||||
))
|
||||
|
||||
ret:get_widget():get_children_by_id("add_task")[1]:buttons(gtable.join(
|
||||
ret:get_widget():get_children_by_id('add_task')[1]:buttons(gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"zenity --info --text='Soon TM'",
|
||||
@@ -919,54 +917,57 @@ function calendar.new(args)
|
||||
end)
|
||||
))
|
||||
|
||||
ret:get_widget():get_children_by_id("prev_month")[1]:buttons(gtable.join(
|
||||
ret:get_widget():get_children_by_id('prev_month')[1]:buttons(gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
ret.date.month = ret.date.month - 1
|
||||
if ret.date.month == 0 then
|
||||
ret.date.month = 12
|
||||
ret.date.year = ret.date.year - 1
|
||||
end
|
||||
ret:get_widget():get_children_by_id("month")[1].text = ret._private.months[ret.date.month]
|
||||
ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
|
||||
ret:get_widget():get_children_by_id('month')[1].text = ret._private.months[ret.date.month]
|
||||
ret:get_widget():get_children_by_id('year')[1].text = ret.date.year
|
||||
ret:create_calendar_weeks_widget()
|
||||
ret:create_calendar_widget()
|
||||
end)
|
||||
))
|
||||
|
||||
ret:get_widget():get_children_by_id("next_month")[1]:buttons(gtable.join(
|
||||
ret:get_widget():get_children_by_id('next_month')[1]:buttons(gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
ret.date.month = ret.date.month + 1
|
||||
if ret.date.month == 13 then
|
||||
ret.date.month = 1
|
||||
ret.date.year = ret.date.year + 1
|
||||
end
|
||||
ret:get_widget():get_children_by_id("month")[1].text = ret._private.months[ret.date.month]
|
||||
ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
|
||||
ret:get_widget():get_children_by_id('month')[1].text = ret._private.months[ret.date.month]
|
||||
ret:get_widget():get_children_by_id('year')[1].text = ret.date.year
|
||||
ret:create_calendar_weeks_widget()
|
||||
ret:create_calendar_widget()
|
||||
end)
|
||||
))
|
||||
|
||||
--- Calendar switch year back
|
||||
ret:get_widget():get_children_by_id("prev_year")[1]:buttons(gtable.join(
|
||||
ret:get_widget():get_children_by_id('prev_year')[1]:buttons(gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
ret.date.year = ret.date.year - 1
|
||||
ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
|
||||
ret:get_widget():get_children_by_id('year')[1].text = ret.date.year
|
||||
ret:create_calendar_weeks_widget()
|
||||
ret:create_calendar_widget()
|
||||
end)
|
||||
))
|
||||
|
||||
--- Calendar switch year forward
|
||||
ret:get_widget():get_children_by_id("next_year")[1]:buttons(gtable.join(
|
||||
ret:get_widget():get_children_by_id('next_year')[1]:buttons(gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
ret.date.year = ret.date.year + 1
|
||||
ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
|
||||
ret:get_widget():get_children_by_id('year')[1].text = ret.date.year
|
||||
ret:create_calendar_weeks_widget()
|
||||
ret:create_calendar_widget()
|
||||
end)
|
||||
))
|
||||
|
||||
hover.bg_hover { widget = ret:get_widget():get_children_by_id('add_ical')[1] }
|
||||
hover.bg_hover { widget = ret:get_widget():get_children_by_id('add_task')[1] }
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gcolor = require("gears.color")
|
||||
local gtable = require("gears.table")
|
||||
local gshape = require("gears.shape")
|
||||
local gobject = require("gears.object")
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local wibox = require("wibox")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gtable = require('gears.table')
|
||||
local gshape = require('gears.shape')
|
||||
local gobject = require('gears.object')
|
||||
local gfilesystem = require('gears').filesystem
|
||||
local wibox = require('wibox')
|
||||
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
}
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/calendar/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/calendar/'
|
||||
|
||||
local task_info = { mt = {} }
|
||||
task_info._private = {}
|
||||
@@ -23,124 +21,126 @@ function task_info.new(args)
|
||||
local ret = gobject {}
|
||||
gtable.crush(ret, task_info, true)
|
||||
|
||||
args.color = args.color or "#ffffff"
|
||||
args.color = args.color or '#ffffff'
|
||||
|
||||
local date_long_written = os.date("%A, %d. %B %Y", os.time(args.date_start))
|
||||
local date_long_written = os.date('%A, %d. %B %Y', os.time(args.date_start))
|
||||
|
||||
local from_to = os.date('%H:%M', os.time(args.date_start)) .. ' - ' .. os.date('%H:%M', os.time(args.date_end))
|
||||
|
||||
local from_to = os.date("%H:%M", os.time(args.date_start)) .. " - " .. os.date("%H:%M", os.time(args.date_end))
|
||||
|
||||
local task_info_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Task detail
|
||||
{ -- Calendar color
|
||||
widget = wibox.container.background,
|
||||
bg = args.color,
|
||||
forced_width = dpi(10),
|
||||
shape = function(cr, _, height)
|
||||
gshape.rounded_rect(cr, dpi(10), height, dpi(8))
|
||||
end,
|
||||
{ -- Task detail
|
||||
{ -- Calendar color
|
||||
widget = wibox.container.background,
|
||||
bg = args.color,
|
||||
forced_width = dpi(10),
|
||||
shape = function(cr, _, height)
|
||||
gshape.rounded_rect(cr, dpi(10), height, dpi(8))
|
||||
end,
|
||||
},
|
||||
{
|
||||
{ -- Summary
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.summary:sub(1, -2) or 'NO SUMMARY',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'summary',
|
||||
},
|
||||
{ -- Date long
|
||||
widget = wibox.widget.textbox,
|
||||
text = date_long_written or '01.12.1970',
|
||||
valign = 'center',
|
||||
halign = 'right',
|
||||
id = 'date_long',
|
||||
},
|
||||
{ -- From - To
|
||||
widget = wibox.widget.textbox,
|
||||
text = from_to or '',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'from_to',
|
||||
},
|
||||
{ -- Repeat information
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.freq or '0',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'repeat_info',
|
||||
}, -- Year
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.date_start.year or '1970',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'year',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
spacing = dpi(20),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
left = dpi(9),
|
||||
},
|
||||
{
|
||||
{ -- Summary
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.summary:sub(1, -2) or "NO SUMMARY",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "summary",
|
||||
{ -- Location
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = gcolor.recolor_image(icondir .. 'location.svg', args.color),
|
||||
resize = false,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
{ -- Date long
|
||||
widget = wibox.widget.textbox,
|
||||
text = date_long_written or "01.12.1970",
|
||||
valign = "center",
|
||||
halign = "right",
|
||||
id = "date_long",
|
||||
},
|
||||
{ -- From - To
|
||||
widget = wibox.widget.textbox,
|
||||
text = from_to or "",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "from_to",
|
||||
},
|
||||
{ -- Repeat information
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.freq or "0",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "repeat_info",
|
||||
}, -- Year
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.date_start.year or "1970",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "year",
|
||||
text = args.location:sub(1, -2) or 'F303',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'location',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
id = 'location_container',
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
spacing = dpi(20),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
{ -- Alarm
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = gcolor.recolor_image(icondir .. 'alarm.svg', args.color),
|
||||
resize = false,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.alarm or 'NO ALARM',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'alarm',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
id = 'alarm_container',
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = 'task_detail',
|
||||
spacing = dpi(15),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
left = dpi(9)
|
||||
},
|
||||
{ -- Location
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = gcolor.recolor_image(icondir .. "location.svg", args.color),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.location:sub(1, -2) or "F303",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "location",
|
||||
},
|
||||
spacing = dpi(10),
|
||||
id = "location_container",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
{ -- Alarm
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = gcolor.recolor_image(icondir .. "alarm.svg", args.color),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.alarm or "NO ALARM",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "alarm",
|
||||
},
|
||||
spacing = dpi(10),
|
||||
id = "alarm_container",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "task_detail",
|
||||
spacing = dpi(15),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
left = dpi(6),
|
||||
right = dpi(15),
|
||||
top = dpi(15),
|
||||
bottom = dpi(15),
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
left = dpi(6),
|
||||
right = dpi(15),
|
||||
top = dpi(15),
|
||||
bottom = dpi(15),
|
||||
},
|
||||
bg = Theme_config.calendar.task_info.bg,
|
||||
fg = Theme_config.calendar.task_info.fg,
|
||||
shape = Theme_config.calendar.task_info.shape,
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
hover.bg_hover { widget = task_info_widget }
|
||||
|
||||
ret.widget = task_info_widget
|
||||
|
||||
return ret.widget
|
||||
|
||||
@@ -2,32 +2,33 @@
|
||||
-- This is the brightness_osd module --
|
||||
---------------------------------------
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local awful = require('awful')
|
||||
local abutton = awful.button
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears.table")
|
||||
local base = require("wibox.widget.base")
|
||||
local wibox = require("wibox")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local gobject = require("gears.object")
|
||||
local gcolor = require("gears.color")
|
||||
local gtimer = require("gears.timer")
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gtable = require('gears.table')
|
||||
local base = require('wibox.widget.base')
|
||||
local wibox = require('wibox')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gcolor = require('gears.color')
|
||||
local gtimer = require('gears.timer')
|
||||
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/context_menu/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/context_menu/'
|
||||
|
||||
local context_menu = {
|
||||
mt = {}
|
||||
mt = {},
|
||||
}
|
||||
|
||||
function context_menu:layout(_, width, height)
|
||||
if self._private.widget then
|
||||
return {
|
||||
base.place_widget_at(self._private.widget, 0, 0, width, height)
|
||||
base.place_widget_at(self._private.widget, 0, 0, width, height),
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -45,7 +46,7 @@ context_menu.set_widget = base.set_widget_common
|
||||
function context_menu:make_entries(wtemplate, entries, spacing)
|
||||
local menu_entries = {
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
spacing = spacing
|
||||
spacing = spacing,
|
||||
}
|
||||
|
||||
if not wtemplate then
|
||||
@@ -53,8 +54,7 @@ function context_menu:make_entries(wtemplate, entries, spacing)
|
||||
end
|
||||
|
||||
for key, entry in pairs(entries) do
|
||||
-- TODO: Figure out how to make a new widget from etemplate
|
||||
local menu_entry = wibox.widget {
|
||||
local menu_entry = base.make_widget_from_value {
|
||||
{
|
||||
{
|
||||
{
|
||||
@@ -62,72 +62,74 @@ function context_menu:make_entries(wtemplate, entries, spacing)
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role"
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'text_role',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
nil,
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "arrow_role"
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'arrow_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.desktop.context_menu.entry_bg,
|
||||
fg = Theme_config.desktop.context_menu.entry_fg,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
Hover_signal(menu_entry)
|
||||
assert(type(menu_entry) == 'table', 'Entry must be a table')
|
||||
|
||||
menu_entry:get_children_by_id("icon_role")[1].image = entry.icon
|
||||
menu_entry:get_children_by_id("text_role")[1].text = entry.name
|
||||
hover.bg_hover { widget = menu_entry }
|
||||
|
||||
menu_entry:get_children_by_id('icon_role')[1].image = entry.icon
|
||||
menu_entry:get_children_by_id('text_role')[1].text = entry.name
|
||||
if entry.submenu then
|
||||
menu_entry:get_children_by_id("arrow_role")[1].image =
|
||||
gcolor.recolor_image(icondir .. "entry.svg", Theme_config.desktop.context_menu.entry_fg)
|
||||
menu_entry:get_children_by_id('arrow_role')[1].image =
|
||||
gcolor.recolor_image(icondir .. 'entry.svg', Theme_config.desktop.context_menu.entry_fg)
|
||||
end
|
||||
gtable.crush(menu_entry, entry, true)
|
||||
|
||||
menu_entry:buttons(gtable.join {
|
||||
abutton({
|
||||
abutton {
|
||||
modifiers = {},
|
||||
button = 1,
|
||||
on_release = function()
|
||||
if not entry.submenu then
|
||||
entry.callback()
|
||||
end
|
||||
capi.awesome.emit_signal("submenu::close")
|
||||
capi.awesome.emit_signal("cm::hide")
|
||||
end
|
||||
})
|
||||
capi.awesome.emit_signal('submenu::close')
|
||||
capi.awesome.emit_signal('cm::hide')
|
||||
end,
|
||||
},
|
||||
})
|
||||
|
||||
if entry.submenu then
|
||||
@@ -139,7 +141,7 @@ function context_menu:make_entries(wtemplate, entries, spacing)
|
||||
border_width = Theme_config.desktop.context_menu.border_width,
|
||||
border_color = Theme_config.desktop.context_menu.border_color,
|
||||
shape = Theme_config.desktop.context_menu.shape,
|
||||
visible = false
|
||||
visible = false,
|
||||
}
|
||||
|
||||
local hide_timer = gtimer {
|
||||
@@ -148,25 +150,25 @@ function context_menu:make_entries(wtemplate, entries, spacing)
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
menu_entry.popup.visible = false
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
menu_entry:connect_signal("mouse::enter", function()
|
||||
menu_entry:connect_signal('mouse::enter', function()
|
||||
-- place widget right of parent
|
||||
menu_entry.popup:move_next_to(capi.mouse.current_widget_geometry)
|
||||
hide_timer:stop()
|
||||
menu_entry.popup.visible = true
|
||||
end)
|
||||
menu_entry.popup:connect_signal("mouse::leave", function()
|
||||
menu_entry.popup:connect_signal('mouse::leave', function()
|
||||
hide_timer:again()
|
||||
end)
|
||||
menu_entry.popup:connect_signal("mouse::enter", function()
|
||||
menu_entry.popup:connect_signal('mouse::enter', function()
|
||||
hide_timer:stop()
|
||||
end)
|
||||
menu_entry:connect_signal("mouse::leave", function()
|
||||
menu_entry:connect_signal('mouse::leave', function()
|
||||
hide_timer:again()
|
||||
end)
|
||||
capi.awesome.connect_signal("submenu::close", function()
|
||||
capi.awesome.connect_signal('submenu::close', function()
|
||||
menu_entry.popup.visible = false
|
||||
end)
|
||||
end
|
||||
@@ -176,8 +178,11 @@ function context_menu:make_entries(wtemplate, entries, spacing)
|
||||
end
|
||||
|
||||
function context_menu:toggle()
|
||||
self.x = capi.mouse.coords().x
|
||||
self.y = capi.mouse.coords().y
|
||||
self.x = capi.mouse.coords().x - dpi(5)
|
||||
self.y = capi.mouse.coords().y - dpi(5)
|
||||
if self.y + self.height > capi.mouse.screen.geometry.height then
|
||||
self.y = self.y - self.height + dpi(10)
|
||||
end
|
||||
self.visible = not self.visible
|
||||
end
|
||||
|
||||
@@ -190,8 +195,10 @@ function context_menu.new(args)
|
||||
|
||||
gtable.crush(ret, context_menu, true)
|
||||
|
||||
local entries = ret:make_entries(args.widget_template, args.entries, args.spacing)
|
||||
|
||||
ret = awful.popup {
|
||||
widget = ret:make_entries(args.widget_template, args.entries, args.spacing),
|
||||
widget = entries,
|
||||
bg = Theme_config.desktop.context_menu.bg,
|
||||
fg = Theme_config.desktop.context_menu.fg,
|
||||
ontop = true,
|
||||
@@ -200,11 +207,11 @@ function context_menu.new(args)
|
||||
shape = Theme_config.desktop.context_menu.shape,
|
||||
visible = false,
|
||||
x = capi.mouse.coords().x + 10,
|
||||
y = capi.mouse.coords().y - 10
|
||||
y = capi.mouse.coords().y - 10,
|
||||
}
|
||||
|
||||
-- I literally have no clue how to do it better, it doesn't really matter anyways
|
||||
capi.awesome.connect_signal("cm::hide", function()
|
||||
capi.awesome.connect_signal('cm::hide', function()
|
||||
ret.visible = false
|
||||
end)
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
-- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen --
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local aplacement = require('awful.placement')
|
||||
local apopup = require('awful.popup')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
@@ -17,7 +17,7 @@ return function(s, widgets)
|
||||
local function prepare_widgets(w)
|
||||
local layout = {
|
||||
forced_height = dpi(50),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
}
|
||||
for i, widget in pairs(w) do
|
||||
if i == 1 then
|
||||
@@ -28,7 +28,7 @@ return function(s, widgets)
|
||||
right = dpi(6),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
elseif i == #w then
|
||||
table.insert(layout,
|
||||
@@ -38,7 +38,7 @@ return function(s, widgets)
|
||||
right = dpi(6),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
else
|
||||
table.insert(layout,
|
||||
@@ -48,28 +48,28 @@ return function(s, widgets)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
end
|
||||
end
|
||||
return layout
|
||||
end
|
||||
|
||||
local top_center = awful.popup {
|
||||
local top_center = apopup {
|
||||
screen = s,
|
||||
widget = prepare_widgets(widgets),
|
||||
ontop = false,
|
||||
bg = Theme_config.center_bar.bg,
|
||||
visible = true,
|
||||
maximum_width = dpi(500),
|
||||
placement = function(c) awful.placement.top(c, { margins = dpi(10) }) end
|
||||
placement = function(c) aplacement.top(c, { margins = dpi(10) }) end,
|
||||
}
|
||||
|
||||
top_center:struts {
|
||||
top = dpi(55)
|
||||
top = dpi(55),
|
||||
}
|
||||
|
||||
capi.client.connect_signal("manage", function(c)
|
||||
capi.client.connect_signal('manage', function(c)
|
||||
if #s.selected_tag:clients() < 1 then
|
||||
top_center.visible = false
|
||||
else
|
||||
@@ -77,7 +77,7 @@ return function(s, widgets)
|
||||
end
|
||||
end)
|
||||
|
||||
capi.client.connect_signal("unmanage", function(c)
|
||||
capi.client.connect_signal('unmanage', function(c)
|
||||
if #s.selected_tag:clients() < 1 then
|
||||
top_center.visible = false
|
||||
else
|
||||
@@ -85,7 +85,7 @@ return function(s, widgets)
|
||||
end
|
||||
end)
|
||||
|
||||
capi.client.connect_signal("property::selected", function(c)
|
||||
capi.client.connect_signal('property::selected', function(c)
|
||||
if #s.selected_tag:clients() < 1 then
|
||||
top_center.visible = false
|
||||
else
|
||||
@@ -93,7 +93,7 @@ return function(s, widgets)
|
||||
end
|
||||
end)
|
||||
|
||||
capi.awesome.connect_signal("refresh", function(c)
|
||||
capi.awesome.connect_signal('refresh', function(c)
|
||||
if #s.selected_tag:clients() < 1 then
|
||||
top_center.visible = false
|
||||
else
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,42 +10,42 @@ return function(s)
|
||||
local widget_table = {}
|
||||
if widgets then
|
||||
for _, widget in ipairs(widgets) do
|
||||
if widget == "Audio" then
|
||||
table.insert(widget_table, require("src.widgets.audio")(s))
|
||||
elseif widget == "Battery" then
|
||||
table.insert(widget_table, require("src.widgets.battery")(User_config.battery_kind))
|
||||
elseif widget == "Bluetooth" then
|
||||
table.insert(widget_table, require("src.widgets.bluetooth")(s))
|
||||
elseif widget == "Clock" then
|
||||
table.insert(widget_table, require("src.widgets.clock")())
|
||||
elseif widget == "Cpu Frequency" then
|
||||
table.insert(widget_table, require("src.widgets.cpu_info")("freq"))
|
||||
elseif widget == "Cpu Temperature" then
|
||||
table.insert(widget_table, require("src.widgets.cpu_info")("temp"))
|
||||
elseif widget == "Cpu Usage" then
|
||||
table.insert(widget_table, require("src.widgets.cpu_info")("usage"))
|
||||
elseif widget == "Date" then
|
||||
table.insert(widget_table, require("src.widgets.date")(s))
|
||||
elseif widget == "Gpu Temperature" then
|
||||
table.insert(widget_table, require("src.widgets.gpu_info")("temp"))
|
||||
elseif widget == "Gpu Usage" then
|
||||
table.insert(widget_table, require("src.widgets.gpu_info")("usage"))
|
||||
elseif widget == "Keyboard Layout" then
|
||||
table.insert(widget_table, require("src.widgets.kblayout")(s))
|
||||
elseif widget == "Tiling Layout" then
|
||||
table.insert(widget_table, require("src.widgets.layout_list")())
|
||||
elseif widget == "Network" then
|
||||
table.insert(widget_table, require("src.widgets.network") { screen = s })
|
||||
elseif widget == "Power Button" then
|
||||
table.insert(widget_table, require("src.widgets.power")())
|
||||
elseif widget == "Ram Usage" then
|
||||
table.insert(widget_table, require("src.widgets.ram_info")())
|
||||
elseif widget == "Systray" then
|
||||
table.insert(widget_table, require("src.widgets.systray")(s))
|
||||
elseif widget == "Taglist" then
|
||||
table.insert(widget_table, require("src.widgets.taglist")(s))
|
||||
elseif widget == "Tasklist" then
|
||||
table.insert(widget_table, require("src.widgets.tasklist")(s))
|
||||
if widget == 'Audio' then
|
||||
table.insert(widget_table, require('src.widgets.audio')(s))
|
||||
elseif widget == 'Battery' then
|
||||
table.insert(widget_table, require('src.widgets.battery')(User_config.battery_kind))
|
||||
elseif widget == 'Bluetooth' then
|
||||
table.insert(widget_table, require('src.widgets.bluetooth')(s))
|
||||
elseif widget == 'Clock' then
|
||||
table.insert(widget_table, require('src.widgets.clock')())
|
||||
elseif widget == 'Cpu Frequency' then
|
||||
table.insert(widget_table, require('src.widgets.cpu_info')('freq'))
|
||||
elseif widget == 'Cpu Temperature' then
|
||||
table.insert(widget_table, require('src.widgets.cpu_info')('temp'))
|
||||
elseif widget == 'Cpu Usage' then
|
||||
table.insert(widget_table, require('src.widgets.cpu_info')('usage'))
|
||||
elseif widget == 'Date' then
|
||||
table.insert(widget_table, require('src.widgets.date')(s))
|
||||
elseif widget == 'Gpu Temperature' then
|
||||
table.insert(widget_table, require('src.widgets.gpu_info')('temp'))
|
||||
elseif widget == 'Gpu Usage' then
|
||||
table.insert(widget_table, require('src.widgets.gpu_info')('usage'))
|
||||
elseif widget == 'Keyboard Layout' then
|
||||
table.insert(widget_table, require('src.widgets.kblayout')(s))
|
||||
elseif widget == 'Tiling Layout' then
|
||||
table.insert(widget_table, require('src.widgets.layout_list')())
|
||||
elseif widget == 'Network' then
|
||||
table.insert(widget_table, require('src.widgets.network') { screen = s })
|
||||
elseif widget == 'Power Button' then
|
||||
table.insert(widget_table, require('src.widgets.power')())
|
||||
elseif widget == 'Ram Usage' then
|
||||
table.insert(widget_table, require('src.widgets.ram_info')())
|
||||
elseif widget == 'Systray' then
|
||||
table.insert(widget_table, require('src.widgets.systray')())
|
||||
elseif widget == 'Taglist' then
|
||||
table.insert(widget_table, require('src.widgets.taglist')(s))
|
||||
elseif widget == 'Tasklist' then
|
||||
table.insert(widget_table, require('src.widgets.tasklist')(s))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -56,16 +56,16 @@ return function(s)
|
||||
for index, screen in ipairs(User_config.crylia_bar) do
|
||||
if index == s.index then
|
||||
if screen.left_bar then
|
||||
require("src.modules.crylia_bar.left_bar")(s, get_widgets(screen.left_bar))
|
||||
require('src.modules.crylia_bar.left_bar')(s, get_widgets(screen.left_bar))
|
||||
end
|
||||
if screen.center_bar then
|
||||
require("src.modules.crylia_bar.center_bar")(s, get_widgets(screen.center_bar))
|
||||
require('src.modules.crylia_bar.center_bar')(s, get_widgets(screen.center_bar))
|
||||
end
|
||||
if screen.right_bar then
|
||||
require("src.modules.crylia_bar.right_bar")(s, get_widgets(screen.right_bar))
|
||||
require('src.modules.crylia_bar.right_bar')(s, get_widgets(screen.right_bar))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
require("src.modules.crylia_bar.dock")(s)
|
||||
require('src.modules.crylia_bar.dock') { screen = s }
|
||||
end
|
||||
|
||||
@@ -2,16 +2,15 @@
|
||||
-- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen --
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local wibox = require("wibox")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
|
||||
return function(s, w)
|
||||
|
||||
local function prepare_widgets(widgets)
|
||||
local layout = {
|
||||
forced_height = dpi(50),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
}
|
||||
for i, widget in pairs(widgets) do
|
||||
if i == 1 then
|
||||
@@ -22,7 +21,7 @@ return function(s, w)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
elseif i == #widgets then
|
||||
table.insert(layout,
|
||||
@@ -32,7 +31,7 @@ return function(s, w)
|
||||
right = dpi(6),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
else
|
||||
table.insert(layout,
|
||||
@@ -42,7 +41,7 @@ return function(s, w)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -50,17 +49,17 @@ return function(s, w)
|
||||
end
|
||||
|
||||
local top_left = awful.popup {
|
||||
screen = s,
|
||||
widget = prepare_widgets(w),
|
||||
ontop = false,
|
||||
bg = Theme_config.left_bar.bg,
|
||||
visible = true,
|
||||
maximum_width = dpi(650),
|
||||
placement = function(c) awful.placement.top_left(c, { margins = dpi(10) }) end
|
||||
}
|
||||
screen = s,
|
||||
widget = prepare_widgets(w),
|
||||
ontop = false,
|
||||
bg = Theme_config.left_bar.bg,
|
||||
visible = true,
|
||||
maximum_width = dpi(650),
|
||||
placement = function(c) awful.placement.top_left(c, { margins = dpi(10) }) end,
|
||||
}
|
||||
|
||||
top_left:struts {
|
||||
top = dpi(55)
|
||||
top = dpi(55),
|
||||
}
|
||||
|
||||
Global_config.top_struts = dpi(55)
|
||||
|
||||
@@ -2,16 +2,15 @@
|
||||
-- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen --
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local wibox = require("wibox")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
|
||||
return function(s, w)
|
||||
|
||||
local function prepare_widgets(widgets)
|
||||
local layout = {
|
||||
forced_height = dpi(50),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
}
|
||||
for i, widget in pairs(widgets) do
|
||||
if i == 1 then
|
||||
@@ -22,7 +21,7 @@ return function(s, w)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
elseif i == #widgets then
|
||||
table.insert(layout,
|
||||
@@ -32,7 +31,7 @@ return function(s, w)
|
||||
right = dpi(6),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
else
|
||||
table.insert(layout,
|
||||
@@ -42,7 +41,7 @@ return function(s, w)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -55,11 +54,11 @@ return function(s, w)
|
||||
bg = Theme_config.right_bar.bg,
|
||||
visible = true,
|
||||
screen = s,
|
||||
placement = function(c) awful.placement.top_right(c, { margins = dpi(10) }) end
|
||||
placement = function(c) awful.placement.top_right(c, { margins = dpi(10) }) end,
|
||||
}
|
||||
|
||||
top_right:struts {
|
||||
top = dpi(55)
|
||||
top = dpi(55),
|
||||
}
|
||||
|
||||
Global_config.top_struts = top_right
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
-- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen --
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
local wibox = require("wibox")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gshape = require("gears.shape")
|
||||
local wibox = require('wibox')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gshape = require('gears.shape')
|
||||
|
||||
return function(s)
|
||||
---Lookup function to return the widget from its easy name string
|
||||
@@ -13,42 +13,42 @@ return function(s)
|
||||
local widget_table = {}
|
||||
if widgets then
|
||||
for _, widget in ipairs(widgets) do
|
||||
if widget == "Audio" then
|
||||
table.insert(widget_table, require("src.widgets.audio")(s))
|
||||
elseif widget == "Battery" then
|
||||
table.insert(widget_table, require("src.widgets.battery")(User_config.battery_kind))
|
||||
elseif widget == "Bluetooth" then
|
||||
table.insert(widget_table, require("src.widgets.bluetooth")())
|
||||
elseif widget == "Clock" then
|
||||
table.insert(widget_table, require("src.widgets.clock")())
|
||||
elseif widget == "Cpu Frequency" then
|
||||
table.insert(widget_table, require("src.widgets.cpu_info")("freq", User_config.cpu_frequency))
|
||||
elseif widget == "Cpu Temperature" then
|
||||
table.insert(widget_table, require("src.widgets.cpu_info")("temp"))
|
||||
elseif widget == "Cpu Usage" then
|
||||
table.insert(widget_table, require("src.widgets.cpu_info")("usage"))
|
||||
elseif widget == "Date" then
|
||||
table.insert(widget_table, require("src.widgets.date")())
|
||||
elseif widget == "Gpu Temperature" then
|
||||
table.insert(widget_table, require("src.widgets.gpu_info")("temp"))
|
||||
elseif widget == "Gpu Usage" then
|
||||
table.insert(widget_table, require("src.widgets.gpu_info")("usage"))
|
||||
elseif widget == "Keyboard Layout" then
|
||||
table.insert(widget_table, require("src.widgets.kblayout")(s))
|
||||
elseif widget == "Tiling Layout" then
|
||||
table.insert(widget_table, require("src.widgets.layout_list")())
|
||||
elseif widget == "Network" then
|
||||
table.insert(widget_table, require("src.widgets.network")())
|
||||
elseif widget == "Power Button" then
|
||||
table.insert(widget_table, require("src.widgets.power")())
|
||||
elseif widget == "Ram Usage" then
|
||||
table.insert(widget_table, require("src.widgets.ram_info")())
|
||||
elseif widget == "Systray" then
|
||||
table.insert(widget_table, require("src.widgets.systray")(s))
|
||||
elseif widget == "Taglist" then
|
||||
table.insert(widget_table, require("src.widgets.taglist")(s))
|
||||
elseif widget == "Tasklist" then
|
||||
table.insert(widget_table, require("src.widgets.tasklist")(s))
|
||||
if widget == 'Audio' then
|
||||
table.insert(widget_table, require('src.widgets.audio')(s))
|
||||
elseif widget == 'Battery' then
|
||||
table.insert(widget_table, require('src.widgets.battery')(User_config.battery_kind))
|
||||
elseif widget == 'Bluetooth' then
|
||||
table.insert(widget_table, require('src.widgets.bluetooth')())
|
||||
elseif widget == 'Clock' then
|
||||
table.insert(widget_table, require('src.widgets.clock')())
|
||||
elseif widget == 'Cpu Frequency' then
|
||||
table.insert(widget_table, require('src.widgets.cpu_info')('freq', User_config.cpu_frequency))
|
||||
elseif widget == 'Cpu Temperature' then
|
||||
table.insert(widget_table, require('src.widgets.cpu_info')('temp'))
|
||||
elseif widget == 'Cpu Usage' then
|
||||
table.insert(widget_table, require('src.widgets.cpu_info')('usage'))
|
||||
elseif widget == 'Date' then
|
||||
table.insert(widget_table, require('src.widgets.date')())
|
||||
elseif widget == 'Gpu Temperature' then
|
||||
table.insert(widget_table, require('src.widgets.gpu_info')('temp'))
|
||||
elseif widget == 'Gpu Usage' then
|
||||
table.insert(widget_table, require('src.widgets.gpu_info')('usage'))
|
||||
elseif widget == 'Keyboard Layout' then
|
||||
table.insert(widget_table, require('src.widgets.kblayout')(s))
|
||||
elseif widget == 'Tiling Layout' then
|
||||
table.insert(widget_table, require('src.widgets.layout_list')())
|
||||
elseif widget == 'Network' then
|
||||
table.insert(widget_table, require('src.widgets.network')())
|
||||
elseif widget == 'Power Button' then
|
||||
table.insert(widget_table, require('src.widgets.power')())
|
||||
elseif widget == 'Ram Usage' then
|
||||
table.insert(widget_table, require('src.widgets.ram_info')())
|
||||
elseif widget == 'Systray' then
|
||||
table.insert(widget_table, require('src.widgets.systray')())
|
||||
elseif widget == 'Taglist' then
|
||||
table.insert(widget_table, require('src.widgets.taglist')(s))
|
||||
elseif widget == 'Tasklist' then
|
||||
table.insert(widget_table, require('src.widgets.tasklist')(s))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -61,7 +61,7 @@ return function(s)
|
||||
local function prepare_widgets(widgets)
|
||||
local layout = {
|
||||
forced_height = dpi(50),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
}
|
||||
for i, widget in pairs(widgets) do
|
||||
if i == 1 then
|
||||
@@ -72,7 +72,7 @@ return function(s)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
elseif i == #widgets then
|
||||
table.insert(layout,
|
||||
@@ -82,7 +82,7 @@ return function(s)
|
||||
right = dpi(6),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
else
|
||||
table.insert(layout,
|
||||
@@ -92,7 +92,7 @@ return function(s)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -109,17 +109,17 @@ return function(s)
|
||||
visible = true,
|
||||
x = 0,
|
||||
y = 1035,
|
||||
type = "desktop",
|
||||
type = 'desktop',
|
||||
height = dpi(55),
|
||||
width = 1920,
|
||||
bg = "#212121",
|
||||
bg = '#212121',
|
||||
shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, 8)
|
||||
end,
|
||||
}
|
||||
|
||||
w:struts {
|
||||
bottom = dpi(55)
|
||||
bottom = dpi(55),
|
||||
}
|
||||
|
||||
Global_config.bottom_struts = dpi(55)
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
local base = require("wibox.widget.base")
|
||||
local awful = require("awful")
|
||||
local gtable = require("gears.table")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local gcolor = require("gears.color")
|
||||
local wibox = require("wibox")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gobject = require("gears.object")
|
||||
|
||||
|
||||
local cm = require("src.modules.context_menu.init")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome
|
||||
}
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/desktop/"
|
||||
|
||||
local context_menu = { mt = {} }
|
||||
context_menu._private = {}
|
||||
|
||||
function context_menu:toggle()
|
||||
self._private.popup.x = mouse.coords().x - 10
|
||||
self._private.popup.y = mouse.coords().y - 10
|
||||
self._private.popup.visible = not self._private.popup.visible
|
||||
end
|
||||
|
||||
function context_menu.new(args)
|
||||
args = args or {}
|
||||
|
||||
local ret = gobject {}
|
||||
gtable.crush(ret, context_menu, true)
|
||||
|
||||
capi.awesome.connect_signal("context_menu:show", function()
|
||||
ret:toggle()
|
||||
mousegrabber.run(function()
|
||||
if mouse.current_wibox ~= ret._private.popup then
|
||||
ret:toggle()
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end, nil)
|
||||
end)
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function context_menu.mt:__call(...)
|
||||
return context_menu.new(...)
|
||||
end
|
||||
|
||||
return setmetatable(context_menu, context_menu.mt)
|
||||
@@ -1,33 +1,30 @@
|
||||
local base = require("wibox.widget.base")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears.table")
|
||||
local gshape = require("gears.shape")
|
||||
local grid = require("wibox.layout.grid")
|
||||
local wibox = require("wibox")
|
||||
local abutton = require("awful.button")
|
||||
local awful = require("awful")
|
||||
local gcolor = require("gears.color")
|
||||
local json = require("src.lib.json-lua.json-lua")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local Gio = require("lgi").Gio
|
||||
local Gio = require('lgi').Gio
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local grid = require('wibox.layout.grid')
|
||||
local gshape = require('gears.shape')
|
||||
local gtable = require('gears.table')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local element = require("src.modules.desktop.element")
|
||||
local cm = require("src.modules.context_menu.init")
|
||||
local config = require('src.tools.config')
|
||||
local element = require('src.modules.desktop.element')
|
||||
local cm = require('src.modules.context_menu.init')
|
||||
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
awesome = awesome,
|
||||
screen = screen,
|
||||
}
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/desktop/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/desktop/'
|
||||
|
||||
local desktop = { mt = {} }
|
||||
|
||||
function desktop:save_layout()
|
||||
local layout = {}
|
||||
|
||||
local dir = gfilesystem.get_configuration_dir() .. "src/config/files/desktop/icons/"
|
||||
local dir = gfilesystem.get_configuration_dir() .. 'src/config/files/desktop/icons/'
|
||||
if not gfilesystem.dir_readable(dir) then
|
||||
gfilesystem.make_directories(dir)
|
||||
end
|
||||
@@ -40,54 +37,45 @@ function desktop:save_layout()
|
||||
col = pos.col,
|
||||
widget = {
|
||||
icon = widget.icon,
|
||||
label = widget:get_children_by_id("text_role")[1].text,
|
||||
label = widget.label,
|
||||
exec = widget.exec,
|
||||
icon_size = widget.icon_size
|
||||
}
|
||||
icon_size = widget.icon_size,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
dir = gfilesystem.get_configuration_dir() .. "src/config"
|
||||
dir = gfilesystem.get_configuration_dir() .. 'src/config/desktop.json'
|
||||
gfilesystem.make_directories(dir)
|
||||
if not gfilesystem.file_readable(dir .. "/desktop.json") then
|
||||
os.execute("touch " .. dir .. "/desktop.json")
|
||||
end
|
||||
local handler = io.open(dir .. "/desktop.json", "w")
|
||||
if not handler then return end
|
||||
|
||||
handler:write(json:encode(layout))
|
||||
handler:close()
|
||||
config.write_json(dir, layout)
|
||||
end
|
||||
|
||||
function desktop:load_layout()
|
||||
local dir = gfilesystem.get_configuration_dir() .. "src/config"
|
||||
if not gfilesystem.file_readable(dir .. "/desktop.json") then
|
||||
return
|
||||
end
|
||||
local handler = io.open(dir .. "/desktop.json", "r")
|
||||
if not handler then return end
|
||||
local dir = gfilesystem.get_configuration_dir() .. 'src/config/desktop.json'
|
||||
if not gfilesystem.file_readable(dir) then return end
|
||||
|
||||
local layout = json:decode(handler:read("*all"))
|
||||
handler:close()
|
||||
if not layout then return end
|
||||
for i, value in pairs(layout) do
|
||||
local data = config.read_json(dir)
|
||||
if not data then return end
|
||||
for _, value in pairs(data) do
|
||||
self:add_element(value.widget, { x = value.row, y = value.col })
|
||||
end
|
||||
end
|
||||
|
||||
function desktop:get_element_at(x, y)
|
||||
return self.widget.mrgn.grid:get_widgets_at(x, y)[1]
|
||||
local w = self.widget.mrgn.grid:get_widgets_at(x, y)
|
||||
return w and w[1] or nil
|
||||
end
|
||||
|
||||
function desktop:add_desktop_file(app_info)
|
||||
self:add_element({
|
||||
self:add_element {
|
||||
icon = app_info.icon,
|
||||
label = app_info.label,
|
||||
exec = app_info.exec,
|
||||
icon_size = dpi(96),
|
||||
icon_size = dpi(48),
|
||||
desktop_file = app_info.desktop_file,
|
||||
parent = self.widget.mrgn.grid,
|
||||
})
|
||||
width = self.widget_width,
|
||||
height = self.widget_height,
|
||||
}
|
||||
end
|
||||
|
||||
--[[
|
||||
@@ -98,18 +86,17 @@ function desktop:remove_element(e)
|
||||
end
|
||||
|
||||
function desktop:get_grid_index_at(y, x)
|
||||
local col, row = 1, 1
|
||||
local margin_x, margin_y = dpi(10), dpi(10)
|
||||
local screen_width, screen_height = self.args.screen.geometry.width - margin_x * 2, self.args.screen.geometry.height - dpi(75) - dpi(95) - margin_y * 2
|
||||
local cell_width, cell_height = screen_width / 20, screen_height / 11
|
||||
|
||||
local width = dpi(96) * 1.75 * (4 / 3)
|
||||
local height = dpi(96) * 1.75
|
||||
local spacing = dpi(10)
|
||||
local col = math.floor((x - margin_x) / cell_width) + 1
|
||||
col = math.min(col, 20)
|
||||
col = math.max(col, 1)
|
||||
|
||||
while width * col + spacing * (col - 1) < x do
|
||||
col = col + 1
|
||||
end
|
||||
while height * row + spacing * (row - 1) < y do
|
||||
row = row + 1
|
||||
end
|
||||
local row = math.floor((y - margin_y) / cell_height) + 1
|
||||
row = math.min(row, 11)
|
||||
row = math.max(row, 1)
|
||||
|
||||
return col, row
|
||||
end
|
||||
@@ -133,7 +120,9 @@ function desktop:add_element(args, pos)
|
||||
exec = args.exec,
|
||||
icon_size = args.icon_size,
|
||||
desktop_file = args.desktop_file,
|
||||
parent = args.parent
|
||||
parent = args.parent,
|
||||
width = self.widget_width,
|
||||
height = self.widget_height,
|
||||
}
|
||||
|
||||
local cm_popup = cm {
|
||||
@@ -144,106 +133,98 @@ function desktop:add_element(args, pos)
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'text_role',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
entries = {
|
||||
{
|
||||
name = "Open with",
|
||||
icon = gcolor.recolor_image(icondir .. "launch.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Open with',
|
||||
icon = gcolor.recolor_image(icondir .. 'launch.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
submenu = {
|
||||
--!TODO: Fetch programs and add them as entries
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "Copy",
|
||||
icon = gcolor.recolor_image(icondir .. "copy.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Copy',
|
||||
icon = gcolor.recolor_image(icondir .. 'copy.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Cut",
|
||||
icon = gcolor.recolor_image(icondir .. "cut.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Cut',
|
||||
icon = gcolor.recolor_image(icondir .. 'cut.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Rename",
|
||||
icon = gcolor.recolor_image(icondir .. "edit.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Rename',
|
||||
icon = gcolor.recolor_image(icondir .. 'edit.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Remove",
|
||||
icon = gcolor.recolor_image(icondir .. "delete.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Remove',
|
||||
icon = gcolor.recolor_image(icondir .. 'delete.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
self:remove_element(e)
|
||||
self:save_layout()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Actions",
|
||||
icon = gcolor.recolor_image(icondir .. "dots-vertical.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Actions',
|
||||
icon = gcolor.recolor_image(icondir .. 'dots-vertical.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
submenu = {
|
||||
-- TODO: fetch actions from desktop file
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
cm_popup:connect_signal("mouse::leave", function()
|
||||
cm_popup:connect_signal('mouse::leave', function()
|
||||
cm_popup.visible = false
|
||||
end)
|
||||
|
||||
local cols = math.floor(self.args.screen.geometry.width / (args.icon_size * 1.75 * (4 / 3)))
|
||||
local rows = math.floor((self.args.screen.geometry.height - 75 + 95) / (args.icon_size * 1.75))
|
||||
print(cols, rows)
|
||||
-- While the mouse is down, remove the element from the grid and add it to manual then move it
|
||||
-- until the mouse is released and then add it back to the grid.
|
||||
e:connect_signal("button::press", function(_, _, _, b)
|
||||
local start_pos = mouse.coords()
|
||||
|
||||
e:connect_signal('button::press', function(_, _, _, b)
|
||||
if not mousegrabber.isrunning() then
|
||||
|
||||
local width = (self.args.screen.geometry.width - 20 - ((cols - 1) * 10)) / cols
|
||||
local height = (self.args.screen.geometry.height - 170 - 20) / rows
|
||||
|
||||
local dnd_widget = element {
|
||||
icon = args.icon,
|
||||
label = args.label,
|
||||
on_click = args.on_click,
|
||||
exec = args.exec,
|
||||
icon_size = args.icon_size,
|
||||
desktop_file = args.desktop_file,
|
||||
parent = args.parent,
|
||||
width = width,
|
||||
height = height,
|
||||
width = self.widget_width,
|
||||
height = self.widget_height,
|
||||
}
|
||||
dnd_widget.visible = false
|
||||
|
||||
dnd_widget:get_children_by_id("icon_role")[1].opacity = 0.6
|
||||
|
||||
local xp, yp = capi.mouse.coords()
|
||||
dnd_widget.point = { x = xp, y = yp }
|
||||
dnd_widget:get_children_by_id('icon_role')[1].opacity = 0.6
|
||||
|
||||
local start_pos = capi.mouse.coords()
|
||||
dnd_widget.point = { x = math.floor(start_pos.x - self.args.screen.geometry.x), y = math.floor(start_pos.y - self.args.screen.geometry.y) }
|
||||
local old_pos = self.widget.mrgn.grid:get_widget_position(e)
|
||||
self.widget.manual:add(dnd_widget)
|
||||
mousegrabber.run(function(m)
|
||||
@@ -254,22 +235,29 @@ function desktop:add_element(args, pos)
|
||||
m.buttons[1] then
|
||||
self:remove_element(e)
|
||||
dnd_widget.visible = true
|
||||
dnd_widget.bg = gcolor("#0ffff088")
|
||||
dnd_widget.border_color = gcolor("#0ffff0")
|
||||
self.widget.manual:move_widget(dnd_widget, { x = m.x - dnd_widget.width / 2, y = m.y - dnd_widget.height / 2 })
|
||||
dnd_widget.bg = gcolor('#0ffff088')
|
||||
dnd_widget.border_color = gcolor('#0ffff0')
|
||||
|
||||
self.widget.manual:move_widget(dnd_widget, {
|
||||
x = (m.x - dnd_widget.width / 2) - self.args.screen.geometry.x,
|
||||
y = (m.y - dnd_widget.height / 2) - self.args.screen.geometry.y,
|
||||
})
|
||||
end
|
||||
|
||||
if not m.buttons[1] then
|
||||
if b == 1 then
|
||||
dnd_widget.bg = gcolor("#0ffff088")
|
||||
dnd_widget.border_color = gcolor("#0ffff0")
|
||||
dnd_widget.bg = gcolor('#0ffff088')
|
||||
dnd_widget.border_color = gcolor('#0ffff0')
|
||||
|
||||
if dnd_widget.visible then
|
||||
dnd_widget.visible = false
|
||||
|
||||
local np_x, np_y = self:get_grid_index_at(m.y, m.x)
|
||||
if not self.widget.mrgn.grid:get_widgets_at(np_y, np_x) then
|
||||
self.widget.mrgn.grid:add_widget_at(e, np_y, np_x)
|
||||
local newp_x, newp_y = self:get_grid_index_at(
|
||||
(m.y - dnd_widget.height / 2) - self.args.screen.geometry.y,
|
||||
(m.x - dnd_widget.width / 2) - self.args.screen.geometry.x
|
||||
)
|
||||
if not self.widget.mrgn.grid:get_widgets_at(newp_y, newp_x) then
|
||||
self.widget.mrgn.grid:add_widget_at(e, newp_y, newp_x)
|
||||
self:save_layout()
|
||||
else
|
||||
self.widget.mrgn.grid:add_widget_at(e, old_pos.row, old_pos.col)
|
||||
@@ -286,7 +274,7 @@ function desktop:add_element(args, pos)
|
||||
end
|
||||
|
||||
return m.buttons[1]
|
||||
end, "left_ptr")
|
||||
end, 'left_ptr')
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -299,62 +287,83 @@ function desktop:draw_selector()
|
||||
if not mousegrabber.isrunning() then
|
||||
local selector = wibox.widget {
|
||||
widget = wibox.container.background,
|
||||
bg = gcolor("#0ffff088"),
|
||||
border_color = gcolor("#0ffff0"),
|
||||
bg = gcolor('#0ffff088'),
|
||||
border_color = gcolor('#0ffff0'),
|
||||
border_width = dpi(2),
|
||||
forced_width = 0,
|
||||
forced_height = 0,
|
||||
x = start_pos.x,
|
||||
y = start_pos.y,
|
||||
x = start_pos.x - self.args.screen.geometry.x,
|
||||
y = start_pos.y - self.args.screen.geometry.y,
|
||||
visible = true,
|
||||
shape = function(cr, w, h)
|
||||
gshape.rounded_rect(cr, w, h, dpi(10))
|
||||
end
|
||||
end,
|
||||
}
|
||||
selector.point = { x = start_pos.x, y = start_pos.y }
|
||||
selector.point = { x = start_pos.x - self.args.screen.geometry.x, y = start_pos.y - self.args.screen.geometry.y }
|
||||
self.widget.manual:add(selector)
|
||||
mousegrabber.run(function(m)
|
||||
if m.buttons[1] then
|
||||
selector.visible = true
|
||||
end
|
||||
if not m.buttons[1] then
|
||||
print("stop")
|
||||
mousegrabber.stop()
|
||||
selector.visible = false
|
||||
self.widget.manual:reset()
|
||||
end
|
||||
selector.forced_width = selector.forced_width + ((start_pos.x - m.x) * -1)
|
||||
selector.forced_height = selector.forced_width + ((start_pos.y - m.y) * -1)
|
||||
|
||||
print(selector.forced_width, selector.forced_height)
|
||||
local dx = m.x - start_pos.x
|
||||
local dy = m.y - start_pos.y
|
||||
local gx, gy = self:get_grid_index_at(math.abs(dy), math.abs(dx))
|
||||
selector.forced_width = math.abs(dx)
|
||||
selector.forced_height = math.abs(dy)
|
||||
--if the mouse is moving to the left, move the widget to the left
|
||||
if dx < 0 then
|
||||
selector.x = start_pos.x - self.args.screen.geometry.x + dx
|
||||
selector.point.x = start_pos.x - self.args.screen.geometry.x + dx
|
||||
gx, gy = self:get_grid_index_at(selector.point.y, selector.point.x)
|
||||
end
|
||||
--if the mouse is moving up, move the widget up
|
||||
if dy < 0 then
|
||||
selector.y = start_pos.y - self.args.screen.geometry.y + dy
|
||||
selector.point.y = start_pos.y - self.args.screen.geometry.y + dy
|
||||
gx, gy = self:get_grid_index_at(selector.point.y, selector.point.x)
|
||||
end
|
||||
-- check if a widget is inside the selector
|
||||
local w = self:get_element_at(gx, gy)
|
||||
if w then
|
||||
w.bg = gcolor('#0ffff088')
|
||||
w.border_color = gcolor('#0ffff0')
|
||||
end
|
||||
return m.buttons[1]
|
||||
end, "left_ptr")
|
||||
end, 'left_ptr')
|
||||
end
|
||||
end
|
||||
|
||||
function desktop:add_xdg()
|
||||
self:add_element({
|
||||
icon = "/usr/share/icons/Papirus-Dark/96x96/places/user-trash.svg",
|
||||
label = "Papierkorb",
|
||||
exec = "nautilus trash:/",
|
||||
icon_size = 96,
|
||||
})
|
||||
self:add_element {
|
||||
icon = '/usr/share/icons/Papirus-Dark/96x96/places/user-trash.svg',
|
||||
label = 'Papierkorb',
|
||||
exec = 'nautilus trash:/',
|
||||
icon_size = dpi(48),
|
||||
}
|
||||
|
||||
self:add_element({
|
||||
icon = "/usr/share/icons/Papirus-Dark/96x96/places/user-home.svg",
|
||||
label = "Persönlicher Ordner",
|
||||
exec = "nautilus file:/home/crylia",
|
||||
icon_size = 96,
|
||||
})
|
||||
self:add_element {
|
||||
icon = '/usr/share/icons/Papirus-Dark/96x96/places/user-home.svg',
|
||||
label = 'Persönlicher Ordner',
|
||||
exec = 'nautilus file:/home/crylia',
|
||||
icon_size = dpi(48),
|
||||
}
|
||||
end
|
||||
|
||||
function desktop.new(args)
|
||||
args = args or {}
|
||||
|
||||
local icon_size = args.icon_size or dpi(96)
|
||||
args.icon_size = dpi(48)
|
||||
|
||||
local rows = 20
|
||||
local cols = 11
|
||||
local h_spacing = dpi(10)
|
||||
local v_spacing = dpi(20)
|
||||
|
||||
local cols = math.floor(args.screen.geometry.width / (icon_size * 1.75 * (4 / 3)))
|
||||
local rows = math.floor((args.screen.geometry.height - 75 + 95) / (icon_size * 1.75))
|
||||
--[[
|
||||
The wibox has a stacked layout with a manual layout over a grid.
|
||||
|
||||
@@ -368,10 +377,10 @@ function desktop.new(args)
|
||||
local w = wibox {
|
||||
ontop = false,
|
||||
visible = true,
|
||||
type = "desktop",
|
||||
type = 'desktop',
|
||||
input_passthrough = false,
|
||||
x = 0,
|
||||
y = 0,
|
||||
x = args.screen.geometry.x,
|
||||
y = args.screen.geometry.y,
|
||||
bg = gcolor.transparent,
|
||||
width = args.screen.geometry.width,
|
||||
height = args.screen.geometry.height,
|
||||
@@ -381,26 +390,27 @@ function desktop.new(args)
|
||||
{
|
||||
layout = grid,
|
||||
homogeneous = true,
|
||||
spacing = 10,
|
||||
expand = true,
|
||||
orientation = "horizontal",
|
||||
forced_num_cols = cols,
|
||||
forced_num_rows = rows,
|
||||
id = "grid",
|
||||
horizontal_spacing = h_spacing,
|
||||
vertical_spacing = v_spacing,
|
||||
expand = false,
|
||||
orientation = 'horizontal',
|
||||
forced_num_cols = rows,
|
||||
forced_num_rows = cols,
|
||||
id = 'grid',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
top = dpi(75),
|
||||
bottom = dpi(95),
|
||||
id = "mrgn"
|
||||
id = 'mrgn',
|
||||
},
|
||||
{
|
||||
layout = wibox.layout.manual,
|
||||
id = "manual",
|
||||
id = 'manual',
|
||||
},
|
||||
layout = wibox.layout.stack,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
w.args = args
|
||||
@@ -413,158 +423,158 @@ function desktop.new(args)
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'text_role',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
entries = {
|
||||
{
|
||||
name = "Create new",
|
||||
icon = gcolor.recolor_image(icondir .. "file_add.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Create new',
|
||||
icon = gcolor.recolor_image(icondir .. 'file_add.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
submenu = {
|
||||
{
|
||||
name = "Folder",
|
||||
icon = gcolor.recolor_image(icondir .. "folder.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Folder',
|
||||
icon = gcolor.recolor_image(icondir .. 'folder.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
--create a new folder and if it exists add a number to the end
|
||||
local folder_name = "New folder"
|
||||
local folder_path = os.getenv("HOME") .. "/Desktop/" .. folder_name
|
||||
local folder_name = 'New folder'
|
||||
local folder_path = os.getenv('HOME') .. '/Desktop/' .. folder_name
|
||||
local i = 1
|
||||
while gfilesystem.dir_readable(folder_path) do
|
||||
folder_name = "New folder " .. "(" .. i .. ")"
|
||||
folder_path = os.getenv("HOME") .. "/Desktop/" .. folder_name
|
||||
folder_name = 'New folder ' .. '(' .. i .. ')'
|
||||
folder_path = os.getenv('HOME') .. '/Desktop/' .. folder_name
|
||||
i = i + 1
|
||||
end
|
||||
gfilesystem.make_directories(folder_path)
|
||||
w:add_element({
|
||||
icon = "/usr/share/icons/Papirus-Dark/24x24/places/folder.svg",
|
||||
w:add_element {
|
||||
icon = '/usr/share/icons/Papirus-Dark/24x24/places/folder.svg',
|
||||
label = folder_name,
|
||||
exec = "nautilus file:\"" .. folder_path .. "\"",
|
||||
icon_size = icon_size,
|
||||
})
|
||||
end
|
||||
exec = 'nautilus file:\"' .. folder_path .. '\"',
|
||||
icon_size = dpi(48),
|
||||
}
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "File",
|
||||
icon = gcolor.recolor_image(icondir .. "file.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'File',
|
||||
icon = gcolor.recolor_image(icondir .. 'file.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
--create new text file and if it exists add a number to the end
|
||||
local file_name = "New file.txt"
|
||||
local file_path = os.getenv("HOME") .. "/Desktop/" .. file_name
|
||||
local file_name = 'New file.txt'
|
||||
local file_path = os.getenv('HOME') .. '/Desktop/' .. file_name
|
||||
local i = 1
|
||||
while gfilesystem.file_readable(file_path) do
|
||||
file_name = "New file " .. "(" .. i .. ")"
|
||||
file_path = os.getenv("HOME") .. "/Desktop/" .. file_name
|
||||
file_name = 'New file ' .. '(' .. i .. ')'
|
||||
file_path = os.getenv('HOME') .. '/Desktop/' .. file_name
|
||||
i = i + 1
|
||||
end
|
||||
awful.spawn.with_shell("touch " .. file_path)
|
||||
w:add_element({
|
||||
icon = "/usr/share/icons/Papirus-Dark/24x24/mimetypes/text-plain.svg",
|
||||
awful.spawn.with_shell('touch ' .. file_path)
|
||||
w:add_element {
|
||||
icon = '/usr/share/icons/Papirus-Dark/24x24/mimetypes/text-plain.svg',
|
||||
label = file_name,
|
||||
exec = "xdg-open " .. file_path,
|
||||
icon_size = icon_size,
|
||||
})
|
||||
end
|
||||
}
|
||||
}
|
||||
exec = 'xdg-open ' .. file_path,
|
||||
icon_size = dpi(48),
|
||||
}
|
||||
end,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "Terminal",
|
||||
icon = gcolor.recolor_image(icondir .. "terminal.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Terminal',
|
||||
icon = gcolor.recolor_image(icondir .. 'terminal.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.terminal)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Web Browser",
|
||||
icon = gcolor.recolor_image(icondir .. "web_browser.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Web Browser',
|
||||
icon = gcolor.recolor_image(icondir .. 'web_browser.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.web_browser)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "File Manager",
|
||||
icon = gcolor.recolor_image(icondir .. "file_manager.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'File Manager',
|
||||
icon = gcolor.recolor_image(icondir .. 'file_manager.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.file_manager)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Text Editor",
|
||||
icon = gcolor.recolor_image(icondir .. "text_editor.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Text Editor',
|
||||
icon = gcolor.recolor_image(icondir .. 'text_editor.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.text_editor)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Music Player",
|
||||
icon = gcolor.recolor_image(icondir .. "music_player.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Music Player',
|
||||
icon = gcolor.recolor_image(icondir .. 'music_player.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.music_player)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Applications",
|
||||
icon = gcolor.recolor_image(icondir .. "application.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Applications',
|
||||
icon = gcolor.recolor_image(icondir .. 'application.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "GTK Settings",
|
||||
icon = gcolor.recolor_image(icondir .. "gtk_settings.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'GTK Settings',
|
||||
icon = gcolor.recolor_image(icondir .. 'gtk_settings.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.gtk_settings)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Energy Settings",
|
||||
icon = gcolor.recolor_image(icondir .. "energy_settings.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Energy Settings',
|
||||
icon = gcolor.recolor_image(icondir .. 'energy_settings.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.energy_manager)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Screen Settings",
|
||||
icon = gcolor.recolor_image(icondir .. "screen_settings.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Screen Settings',
|
||||
icon = gcolor.recolor_image(icondir .. 'screen_settings.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.screen_settings)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Reload Awesome",
|
||||
icon = gcolor.recolor_image(icondir .. "refresh.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Reload Awesome',
|
||||
icon = gcolor.recolor_image(icondir .. 'refresh.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
capi.awesome.restart()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Quit",
|
||||
icon = gcolor.recolor_image(icondir .. "quit.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Quit',
|
||||
icon = gcolor.recolor_image(icondir .. 'quit.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
capi.awesome.quit()
|
||||
end
|
||||
end,
|
||||
},
|
||||
--cm_awesome
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
w.widget.manual:buttons(gtable.join(
|
||||
@@ -583,9 +593,12 @@ function desktop.new(args)
|
||||
|
||||
gtable.crush(w, desktop, true)
|
||||
|
||||
w.widget_width = (args.screen.geometry.width - 20 - ((h_spacing - 1) * rows)) / rows
|
||||
w.widget_height = (args.screen.geometry.height - 170 - ((v_spacing - 1) * cols)) / cols
|
||||
|
||||
w:load_layout()
|
||||
|
||||
capi.awesome.connect_signal("desktop::add_to_desktop", function(args2)
|
||||
capi.awesome.connect_signal('desktop::add_to_desktop', function(args2)
|
||||
w:add_desktop_file(args2)
|
||||
end)
|
||||
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
local base = require("wibox.widget.base")
|
||||
local wibox = require("wibox")
|
||||
local gtable = require("gears.table")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gshape = require("gears.shape")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local gcolor = require("gears.color")
|
||||
local abutton = require("awful.button")
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/desktop/"
|
||||
|
||||
local capi = {
|
||||
mouse = mouse
|
||||
}
|
||||
local base = require('wibox.widget.base')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gshape = require('gears.shape')
|
||||
local gtable = require('gears.table')
|
||||
local lgi = require('lgi')
|
||||
local cairo = lgi.cairo
|
||||
local wibox = require('wibox')
|
||||
|
||||
local element = { mt = {} }
|
||||
|
||||
@@ -34,30 +28,174 @@ function element:get_widget()
|
||||
end
|
||||
|
||||
function element:on_hover()
|
||||
self:connect_signal("mouse::enter", function()
|
||||
self.bg = "#0ffff033"
|
||||
self.border_color = "#0ffff099"
|
||||
self:connect_signal('mouse::enter', function()
|
||||
self.bg = '#0ffff033'
|
||||
self.border_color = '#0ffff099'
|
||||
end)
|
||||
|
||||
--[[ self:connect_signal("mouse::leave", function()
|
||||
self:connect_signal('mouse::leave', function()
|
||||
self.bg = gcolor.transparent
|
||||
self.border_color = gcolor.transparent
|
||||
end) ]]
|
||||
|
||||
self:connect_signal("button::press", function()
|
||||
self.bg = "#0ffff088"
|
||||
self.border_color = "#0ffff0dd"
|
||||
end)
|
||||
|
||||
self:connect_signal("button::release", function()
|
||||
self.bg = "#0ffff033"
|
||||
self.border_color = "#0ffff099"
|
||||
self:connect_signal('button::press', function()
|
||||
self.bg = '#0ffff088'
|
||||
self.border_color = '#0ffff0dd'
|
||||
end)
|
||||
|
||||
self:connect_signal('button::release', function()
|
||||
self.bg = '#0ffff033'
|
||||
self.border_color = '#0ffff099'
|
||||
end)
|
||||
end
|
||||
|
||||
---Get the cairo extents for any text with its give size and font
|
||||
---@param font string A font
|
||||
---@param font_size number Font size
|
||||
---@param text string Text to get the extent for
|
||||
---@param args table Additional arguments
|
||||
---@return userdata cairo.Extent
|
||||
local function cairo_text_extents(font, font_size, text, args)
|
||||
local surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
|
||||
local cr = cairo.Context(surface)
|
||||
cr:select_font_face(font, cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
|
||||
cr:set_font_size(font_size)
|
||||
cr:set_antialias(cairo.Antialias.BEST)
|
||||
return cr:text_extents(text)
|
||||
end
|
||||
|
||||
local function split_string(str, max_width)
|
||||
local line1 = ''
|
||||
local line2 = ''
|
||||
local line1_width = 0
|
||||
local line2_width = 0
|
||||
local font = 'JetBrainsMono Nerd Font'
|
||||
local font_size = dpi(16)
|
||||
local font_args = { cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD }
|
||||
|
||||
for word in str:gmatch('%S+') do
|
||||
local word_width = cairo_text_extents(font, font_size, word, font_args).width
|
||||
if line1_width + word_width < max_width then
|
||||
line1 = line1 .. word .. ' '
|
||||
line1_width = line1_width + word_width
|
||||
else
|
||||
line2 = line2 .. word .. ' '
|
||||
line2_width = line2_width + word_width
|
||||
end
|
||||
end
|
||||
|
||||
return line1, line2
|
||||
end
|
||||
|
||||
---This function takes any text and uses cairo to draw an outline and a shadow
|
||||
---It also wraps the text correctly if max_width would be violated. It only uses two lines for wraping
|
||||
---the rest is cut off.
|
||||
---@param text string Text to be changed
|
||||
---@param max_width number max width the text won't go over
|
||||
---@return cairo.Surface cairo_surface manupulated text as a cairo surface
|
||||
---@return table `width`,`height` The surface dimensions
|
||||
local function outlined_text(text, max_width)
|
||||
local font = 'JetBrainsMono Nerd Font'
|
||||
local font_size = dpi(16)
|
||||
local spacing = dpi(5)
|
||||
local margin = dpi(5)
|
||||
max_width = max_width - (margin * 2)
|
||||
local shadow_offset_x, shadow_offset_y = 1, 1
|
||||
local font_args = { cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD }
|
||||
|
||||
-- Get the dimensions from the text
|
||||
local extents = cairo_text_extents(font, font_size, text, font_args)
|
||||
|
||||
-- if its bigger it needs special treatment
|
||||
if extents.width > max_width then
|
||||
|
||||
local line1, line2 = split_string(text, max_width)
|
||||
|
||||
-- Get the dimensions for both lines
|
||||
local extents1 = cairo_text_extents(font, font_size, line1, font_args)
|
||||
local extents2 = cairo_text_extents(font, font_size, line2, font_args)
|
||||
|
||||
-- The surface width will be the biggest of the two lines
|
||||
local s_width = extents1.width
|
||||
if extents1.width < extents2.width then
|
||||
s_width = extents2.width
|
||||
end
|
||||
|
||||
-- Create a new surface based on the widest line, and both line's height + the spacing between them and the shadow offset
|
||||
local surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, s_width + shadow_offset_x, extents1.height + extents2.height + spacing + (shadow_offset_y * 3))
|
||||
local cr = cairo.Context(surface)
|
||||
|
||||
-- Create the font with best antialias
|
||||
cr:select_font_face(font, cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
|
||||
cr:set_font_size(font_size)
|
||||
cr:set_antialias(cairo.Antialias.BEST)
|
||||
|
||||
-- To center both lines get the surface center then substract half the line width
|
||||
local text_x = s_width / 2 - ((extents1.width) / 2)
|
||||
local text_x2 = s_width / 2 - ((extents2.width) / 2)
|
||||
|
||||
-- This makes the first text to be blow the main text
|
||||
cr:set_operator(cairo.Operator.OVER)
|
||||
|
||||
-- Draw the text shadow
|
||||
cr:move_to(text_x + shadow_offset_x, -extents1.y_bearing + shadow_offset_y)
|
||||
cr:set_source_rgba(0, 0, 0, 0.5)
|
||||
cr:show_text(line1)
|
||||
|
||||
cr:set_operator(cairo.Operator.OVER)
|
||||
|
||||
-- Draw the second shadow
|
||||
cr:move_to(text_x2 + shadow_offset_x, extents1.height + extents2.height + spacing + shadow_offset_y)
|
||||
cr:set_source_rgba(0, 0, 0, 0.5)
|
||||
cr:show_text(line2)
|
||||
|
||||
-- Draw the first and second line
|
||||
cr:move_to(text_x, -extents1.y_bearing)
|
||||
cr:set_source_rgb(1, 1, 1)
|
||||
cr:text_path(line1)
|
||||
cr:move_to(text_x2, extents1.height + extents2.height + spacing)
|
||||
cr:text_path(line2)
|
||||
|
||||
-- Color it and set the stroke
|
||||
cr:fill_preserve()
|
||||
cr:set_source_rgb(0, 0, 0)
|
||||
cr:set_line_width(0.1)
|
||||
cr:stroke()
|
||||
|
||||
return surface, { width = extents.width, height = extents1.height + extents2.height + spacing }
|
||||
else
|
||||
-- The size is the dimension from above the if
|
||||
local surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, extents.width, extents.height + shadow_offset_y)
|
||||
local cr = cairo.Context(surface)
|
||||
|
||||
-- Set the font, then draw the text and its stroke
|
||||
cr:select_font_face(font, cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
|
||||
cr:set_font_size(font_size)
|
||||
|
||||
-- This makes the first text to be blow the main text
|
||||
cr:set_operator(cairo.Operator.OVER)
|
||||
|
||||
-- Draw the text shadow
|
||||
cr:move_to(-extents.x_bearing + shadow_offset_x, -extents.y_bearing + shadow_offset_y)
|
||||
cr:set_source_rgba(0, 0, 0, 0.5)
|
||||
cr:show_text(text)
|
||||
|
||||
cr:move_to(-extents.x_bearing, -extents.y_bearing)
|
||||
cr:set_source_rgb(1, 1, 1)
|
||||
cr:text_path(text)
|
||||
cr:fill_preserve()
|
||||
cr:set_source_rgb(0, 0, 0)
|
||||
cr:set_line_width(0.1)
|
||||
cr:stroke()
|
||||
return surface, { width = extents.width, height = extents.height }
|
||||
end
|
||||
end
|
||||
|
||||
function element.new(args)
|
||||
args = args or {}
|
||||
|
||||
local text_img, size = outlined_text(args.label, args.width)
|
||||
|
||||
local w = base.make_widget_from_value(wibox.widget {
|
||||
{
|
||||
{
|
||||
@@ -66,31 +204,34 @@ function element.new(args)
|
||||
image = args.icon,
|
||||
resize = true,
|
||||
clip_shape = gshape.rounded_rect,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
widget = wibox.widget.imagebox
|
||||
valign = 'top',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
forced_width = args.icon_size,
|
||||
forced_height = args.icon_size,
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
strategy = "exact",
|
||||
height = args.icon_size,
|
||||
width = args.icon_size,
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(5),
|
||||
left = dpi(20),
|
||||
right = dpi(20),
|
||||
bottom = dpi(5),
|
||||
},
|
||||
{
|
||||
text = args.label,
|
||||
id = "text_role",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
image = text_img,
|
||||
resize = false,
|
||||
valign = 'bottom',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.align.vertical,
|
||||
},
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center"
|
||||
},
|
||||
fg = "#ffffff",
|
||||
fg = '#ffffff',
|
||||
bg = gcolor.transparent,
|
||||
border_color = gcolor.transparent,
|
||||
border_width = dpi(2),
|
||||
@@ -102,9 +243,12 @@ function element.new(args)
|
||||
exec = args.exec,
|
||||
icon_size = args.icon_size,
|
||||
icon = args.icon,
|
||||
widget = wibox.container.background
|
||||
label = args.label,
|
||||
widget = wibox.container.background,
|
||||
})
|
||||
|
||||
assert(w, 'No widget returned')
|
||||
|
||||
gtable.crush(w, element, true)
|
||||
|
||||
w:on_hover()
|
||||
|
||||
@@ -2,27 +2,45 @@
|
||||
-- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen --
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local awful = require('awful')
|
||||
|
||||
awful.screen.connect_for_each_screen(function(s)
|
||||
-- Create 9 tags
|
||||
awful.layout.append_default_layouts(User_config.layouts)
|
||||
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, User_config.layouts[1])
|
||||
awful.tag({ '1', '2', '3', '4', '5', '6', '7', '8', '9' }, s, User_config.layouts[1])
|
||||
|
||||
require("src.modules.desktop.desktop") { screen = s }
|
||||
require("src.modules.powermenu.powermenu")(s)
|
||||
require("src.modules.audio.volume_osd") { screen = s }
|
||||
--require("src.modules.audio.volume_controller") { screen = s }
|
||||
require("src.modules.brightness.brightness_osd") { screen = s }
|
||||
require("src.modules.crylia_bar.init")(s)
|
||||
--require("src.modules.crylia_wibox.init")(s)
|
||||
require("src.modules.notification-center.init")(s)
|
||||
require("src.modules.window_switcher.init")(s)
|
||||
require("src.modules.application_launcher.init") { screen = s }
|
||||
--require("src.modules.network_controller.init") { screen = s }
|
||||
require('src.modules.desktop.desktop') { screen = s }
|
||||
require('src.modules.crylia_bar.init')(s)
|
||||
--require('src.modules.crylia_wibox.init')(s)
|
||||
require('src.modules.notification-center.init') { screen = s }
|
||||
--require('src.modules.window_switcher.init')(s)
|
||||
require('src.modules.application_launcher.init') { screen = s }
|
||||
end)
|
||||
|
||||
do
|
||||
require("src.lib.nice") { titlebar_font = User_config.font.bold,
|
||||
titlebar_items = { left = { "icon" }, right = { "minimize", "maximize", "close" } } }
|
||||
end
|
||||
local ip = require('src.modules.inputbox.new') {
|
||||
text = 'inputboxtest',
|
||||
cursor_pos = 4,
|
||||
highlight = {
|
||||
start_pos = 1,
|
||||
end_pos = 4,
|
||||
},
|
||||
text_hint = 'Input Some Text',
|
||||
}
|
||||
|
||||
awful.popup {
|
||||
widget = ip.widget,
|
||||
bg = '#212121',
|
||||
visible = true,
|
||||
screen = 1,
|
||||
placement = awful.placement.centered,
|
||||
}
|
||||
|
||||
--[[ require('src.modules.inputbox.init') {
|
||||
text = 'inputboxtest',
|
||||
cursor_pos = 4,
|
||||
highlight = {
|
||||
start_pos = 5,
|
||||
end_pos = 8,
|
||||
},
|
||||
}
|
||||
]]
|
||||
|
||||
796
awesome/src/modules/inputbox/init.lua
Normal file
796
awesome/src/modules/inputbox/init.lua
Normal file
@@ -0,0 +1,796 @@
|
||||
---------------------------------------------------------------------------
|
||||
-- This widget can be used to type text and get the text from it.
|
||||
--@DOC_wibox_widget_defaults_inputbox_EXAMPLE@
|
||||
--
|
||||
-- @author Rene Kievits
|
||||
-- @copyright 2022, Rene Kievits
|
||||
-- @module awful.widget.inputbox
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local beautiful = require('beautiful')
|
||||
local gtable = require('gears.table')
|
||||
local base = require('wibox.widget.base')
|
||||
local gstring = require('gears.string')
|
||||
local akeygrabber = require('awful.keygrabber')
|
||||
local akey = require('awful.key')
|
||||
local textbox = require('wibox.widget.textbox')
|
||||
local imagebox = require('wibox.widget.imagebox')
|
||||
local cairo = require('lgi').cairo
|
||||
local apopup = require('awful.popup')
|
||||
local aplacement = require('awful.placement')
|
||||
local gsurface = require('gears.surface')
|
||||
local wibox = require('wibox')
|
||||
local abutton = require('awful.button')
|
||||
|
||||
local capi = {
|
||||
selection = selection,
|
||||
mousegrabber = mousegrabber,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
local inputbox = { mt = {} }
|
||||
|
||||
--- Formats the text with a cursor and highlights if set.
|
||||
--[[ local function text_with_cursor(text, cursor_pos, self)
|
||||
local char, spacer, text_start, text_end
|
||||
|
||||
local cursor_fg = beautiful.inputbox_cursor_fg or '#313131'
|
||||
local cursor_bg = beautiful.inputbox_cursor_bg or '#0dccfc'
|
||||
local placeholder_text = self.hint_text or ''
|
||||
local placeholder_fg = beautiful.inputbox_placeholder_fg or '#777777'
|
||||
local highlight_bg = beautiful.inputbox_highlight_bg or '#35ffe4'
|
||||
local highlight_fg = beautiful.inputbox_highlight_fg or '#000000'
|
||||
|
||||
if text == '' then
|
||||
return "<span foreground='" .. placeholder_fg .. "'>" .. placeholder_text .. '</span>'
|
||||
end
|
||||
|
||||
local offset = 0
|
||||
if text:sub(cursor_pos - 1, cursor_pos - 1) == -1 then
|
||||
offset = 1
|
||||
end
|
||||
|
||||
if #text < cursor_pos then
|
||||
char = ' '
|
||||
spacer = ''
|
||||
text_start = gstring.xml_escape(text)
|
||||
text_end = ''
|
||||
else
|
||||
char = gstring.xml_escape(text:sub(cursor_pos, cursor_pos + offset))
|
||||
spacer = ' '
|
||||
text_start = gstring.xml_escape(text:sub(1, cursor_pos - 1))
|
||||
text_end = gstring.xml_escape(text:sub(cursor_pos + offset + 1))
|
||||
end
|
||||
|
||||
if self._private.highlight and self._private.highlight.start_pos and self._private.highlight.end_pos then
|
||||
-- split the text into 3 parts based on the highlight and cursor position
|
||||
local text_start_highlight = gstring.xml_escape(text:sub(1, self._private.highlight.start_pos - 1))
|
||||
local text_highlighted = gstring.xml_escape(text:sub(self._private.highlight.start_pos,
|
||||
self._private.highlight.end_pos))
|
||||
local text_end_highlight = gstring.xml_escape(text:sub(self._private.highlight.end_pos + 1))
|
||||
|
||||
return text_start_highlight ..
|
||||
"<span foreground='" .. highlight_fg .. "' background='" .. highlight_bg .. "'>" ..
|
||||
text_highlighted .. '</span>' .. text_end_highlight
|
||||
else
|
||||
return text_start .. "<span background='" .. cursor_bg .. "' foreground='" .. cursor_fg .. "'>" ..
|
||||
char .. '</span>' .. text_end .. spacer
|
||||
end
|
||||
end ]]
|
||||
|
||||
local function text_extents(text, font, font_size, args)
|
||||
local surface = cairo.ImageSurface(cairo.Format.ARGB32, 0, 0)
|
||||
local cr = cairo.Context(surface)
|
||||
cr:select_font_face(font, args)
|
||||
cr:set_font_size(font_size)
|
||||
return cr:text_extents(text)
|
||||
end
|
||||
|
||||
--[[
|
||||
calculate width/height of the text
|
||||
create new surface with the calculated width/height
|
||||
draw a vertical line on the surface as the cursor
|
||||
the position of the vertical line will be the cursor_pos - text length and the text extend
|
||||
draw the "text" .. "cursor" .. "rest of the text"
|
||||
return the surface
|
||||
|
||||
mouse_coord holds the coordinates where the user clicked
|
||||
if its not empty then draw the cursor where the user clicked,
|
||||
if its on a character then set the cursor to the closest space
|
||||
|
||||
if some text is highlighted then draw the text with the highlights
|
||||
]]
|
||||
--inputbox.text
|
||||
--inputbox.cursor_pos <<-- 1 = before the text, 2 = after the first character, 3 = after the second character, etc
|
||||
--inputbox.highlight <<-- { start_pos, end_pos }
|
||||
--inputbox.mouse_coord <<-- { x, y } (Will be saved after the user clicked, it will only be overwritten when the user clicks again)
|
||||
function inputbox:draw_text_surface(x, override_cursor)
|
||||
-- x can be 0 for the first time its drawn with a default cursor position
|
||||
x = x or 0
|
||||
|
||||
--Colors need to be in rgba 0-1 format, table.unpack is used to unpack the table into function arguments
|
||||
local fg, fg_highlight, bg_highlight, fg_cursor = { 1, 1, 1 }, { 1, 1, 1 }, { 0.1, 1, 1, 0.5 }, { 1, 1, 1 }
|
||||
|
||||
-- Main text_entent mainly to align everything to this one (it knows the highest and lowest point of the text)
|
||||
local text_extent = text_extents(self:get_text(), self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
|
||||
--The offset if so the user has some space to click on the left and right side of the text
|
||||
local start_offset = 4
|
||||
local end_offset = 4
|
||||
local surface = cairo.ImageSurface(cairo.Format.ARGB32, text_extent.width + start_offset + end_offset, text_extent.height)
|
||||
local cr = cairo.Context(surface)
|
||||
|
||||
--Split the text initially into 2 or 3 parts (most likely split again later)
|
||||
local text = self:get_text()
|
||||
local text_start, text_end, text_highlight
|
||||
if self._private.highlight.start_pos ~= self._private.highlight.end_pos then
|
||||
text_start = text:sub(1, self._private.highlight.start_pos - 1)
|
||||
text_highlight = text:sub(self._private.highlight.start_pos, self._private.highlight.end_pos)
|
||||
text_end = text:sub(self._private.highlight.end_pos + 1)
|
||||
else
|
||||
text_start = text:sub(1, self._private.cursor_pos - 1)
|
||||
text_end = text:sub(self._private.cursor_pos)
|
||||
end
|
||||
|
||||
--Figure out the cursor position based on the mouse coordinates
|
||||
if override_cursor then
|
||||
local cursor_pos = 1
|
||||
for i = 1, #text, 1 do
|
||||
-- Not sure if I need new context's to check the character width but I got inconsistent results without it
|
||||
local ccr = cairo.Context(surface)
|
||||
ccr:select_font_face(self.font, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
ccr:set_font_size(self.font_size)
|
||||
local ext_c = ccr:text_extents(text:sub(1, i))
|
||||
if ext_c.width >= x then
|
||||
local cccr = cairo.Context(surface)
|
||||
cccr:select_font_face(self.font, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
cccr:set_font_size(self.font_size)
|
||||
if math.abs(cccr:text_extents(text:sub(1, i - 1)).width - x) <= math.abs(ext_c.width - x) then
|
||||
cursor_pos = i
|
||||
else
|
||||
cursor_pos = i + 1
|
||||
end
|
||||
break
|
||||
else
|
||||
cursor_pos = #text + 1
|
||||
end
|
||||
end
|
||||
self._private.cursor_pos = cursor_pos
|
||||
end
|
||||
-- Text extents for the start and highlight without any splitting (less calculating, text_end is not needed)
|
||||
local text_start_extents = text_extents(text_start, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
local text_highlight_extents = text_extents(text_highlight, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
|
||||
cr:select_font_face(self.font, cairo.FontSlant.NORMAL, cairo.FontWeight.REGULAR)
|
||||
cr:set_font_size(self.font_size)
|
||||
--[[
|
||||
The following code is a bit of a mess because I have to check if the cursor is inside the highlighted text,
|
||||
the text_start or text_end and then split either of them again to draw the cursor between.
|
||||
]]
|
||||
if (self._private.cursor_pos > 1) and text_highlight then
|
||||
-- If the cursor is inside the highlighted text
|
||||
if (self._private.highlight.start_pos <= self._private.cursor_pos) and (self._private.highlight.end_pos >= self._private.cursor_pos) then
|
||||
-- Draw the text_start
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset, -text_extent.y_bearing)
|
||||
cr:show_text(text_start)
|
||||
|
||||
-- split the text_highlight at the cursor_pos
|
||||
local text_highlight_start = text_highlight:sub(1, self._private.cursor_pos - self._private.highlight.start_pos)
|
||||
local text_highlight_end = text_highlight:sub(self._private.cursor_pos - self._private.highlight.start_pos + 1)
|
||||
-- The text_highlight_start extents are needed for the cursor position and the text_highlight_end position
|
||||
local text_highlight_start_extents = text_extents(text_highlight_start, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
|
||||
-- Draw the first highlighted part(text_highlight_start)
|
||||
cr:set_source_rgb(table.unpack(fg_highlight))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_highlight_start)
|
||||
|
||||
-- Draw the cursor
|
||||
cr:set_source_rgb(table.unpack(fg_cursor))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_start_extents.x_advance, text_extent.y_bearing)
|
||||
cr:line_to(start_offset + text_start_extents.x_advance + text_highlight_start_extents.x_advance, text_extent.height)
|
||||
cr:stroke()
|
||||
|
||||
-- Draw the second highlighted part(text_highlight_end)
|
||||
cr:set_source_rgb(table.unpack(fg_highlight))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_highlight_end)
|
||||
|
||||
-- Draw the text_end
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_end)
|
||||
|
||||
-- Draw the background highlight
|
||||
cr:set_source_rgba(table.unpack(bg_highlight))
|
||||
cr:rectangle(start_offset + text_start_extents.x_advance, text_extent.y_advance, text_highlight_extents.width, text_extent.height)
|
||||
cr:fill()
|
||||
elseif self._private.cursor_pos < self._private.highlight.start_pos then -- If its inside the text_start
|
||||
-- Split the text_start at the cursor_pos
|
||||
local text_start_start = text_start:sub(1, self._private.cursor_pos - 1)
|
||||
local text_start_end = text_start:sub(self._private.cursor_pos)
|
||||
-- The text_start_start extents is needed for the cursor position and the text_start_end position
|
||||
local text_start_start_extents = text_extents(text_start_start, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
|
||||
-- Draw the first part of the text_start(text_start_start)
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset, -text_extent.y_bearing)
|
||||
cr:show_text(text_start_start)
|
||||
|
||||
-- Draw the cursor
|
||||
cr:set_source_rgb(table.unpack(fg_cursor))
|
||||
cr:move_to(start_offset + text_start_start_extents.x_advance, text_extent.y_bearing)
|
||||
cr:line_to(start_offset + text_start_start_extents.x_advance, text_extent.height)
|
||||
cr:stroke()
|
||||
|
||||
-- Draw the second part of the text_start(text_start_end)
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset + text_start_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_start_end)
|
||||
|
||||
-- Draw the text_highlight
|
||||
cr:set_source_rgb(table.unpack(fg_highlight))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_highlight)
|
||||
|
||||
-- Draw the text_end
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_end)
|
||||
|
||||
-- Draw the highlight background
|
||||
cr:set_source_rgba(table.unpack(bg_highlight))
|
||||
cr:rectangle(start_offset + text_start_extents.x_advance, text_extent.y_advance, text_highlight_extents.width, text_extent.height)
|
||||
cr:fill()
|
||||
elseif self._private.cursor_pos > self._private.highlight.end_pos then -- If its inside the text_end
|
||||
-- Draw the text start
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset, -text_extent.y_bearing)
|
||||
cr:show_text(text_start)
|
||||
|
||||
-- Draw the text highlight
|
||||
cr:set_source_rgb(table.unpack(fg_highlight))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_highlight)
|
||||
|
||||
--split the text_end at the cursor_pos
|
||||
local text_end_start = text_end:sub(1, self._private.cursor_pos - self._private.highlight.end_pos - 1)
|
||||
local text_end_end = text_end:sub(self._private.cursor_pos - self._private.highlight.end_pos)
|
||||
-- Text end_start extents needed for the cursor position and the text_end_end
|
||||
local text_end_start_extents = text_extents(text_end_start, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
|
||||
-- Draw the first part of the text_end (text_end_start)
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_end_start)
|
||||
|
||||
-- Draw the cursor
|
||||
cr:set_source_rgb(table.unpack(fg_cursor))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance + text_end_start_extents.x_advance, text_extent.y_bearing)
|
||||
cr:line_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance + text_end_start_extents.x_advance, text_extent.height)
|
||||
cr:stroke()
|
||||
|
||||
-- Draw the second part of the text_end (text_end_end)
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance + text_end_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_end_end)
|
||||
|
||||
-- Draw the highlight background
|
||||
cr:set_source_rgba(table.unpack(bg_highlight))
|
||||
cr:rectangle(start_offset + text_start_extents.x_advance, text_extent.y_advance, text_highlight_extents.width, text_extent.height)
|
||||
cr:fill()
|
||||
end
|
||||
else -- If the cursor is all the way to the left no split is needed
|
||||
-- text_start
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset, -text_extent.y_bearing)
|
||||
cr:show_text(text_start)
|
||||
|
||||
-- Cursor
|
||||
cr:set_source_rgb(table.unpack(fg_cursor))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance, text_extent.y_bearing)
|
||||
cr:line_to(start_offset + text_start_extents.x_advance, text_extent.height)
|
||||
cr:stroke()
|
||||
|
||||
-- text_highlight
|
||||
if text_highlight then
|
||||
cr:set_source_rgb(table.unpack(fg_highlight))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_highlight)
|
||||
cr:set_source_rgba(table.unpack(bg_highlight))
|
||||
cr:rectangle(start_offset + text_start_extents.x_advance, text_extent.y_advance, text_highlight_extents.width, text_extent.height)
|
||||
cr:fill()
|
||||
end
|
||||
|
||||
-- text_end
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset + text_highlight_extents.x_advance + text_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_end)
|
||||
end
|
||||
return surface
|
||||
end
|
||||
|
||||
function inputbox:layout(_, width, height)
|
||||
if self._private.widget then
|
||||
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
|
||||
end
|
||||
end
|
||||
|
||||
function inputbox:fit(context, width, height)
|
||||
local w, h = 0, 0
|
||||
if self._private.widget then
|
||||
w, h = base.fit_widget(self, context, self._private.widget, width, height)
|
||||
end
|
||||
return w, h
|
||||
end
|
||||
|
||||
inputbox.set_widget = base.set_widget_common
|
||||
|
||||
--- Clears the current text
|
||||
function inputbox:clear()
|
||||
self:set_text('')
|
||||
end
|
||||
|
||||
function inputbox:get_text()
|
||||
return self._private.text or ''
|
||||
end
|
||||
|
||||
function inputbox:set_text(text)
|
||||
self._private.text = text
|
||||
--self.markup = text_with_cursor(self:get_text(), #self:get_text(), self)
|
||||
self:emit_signal('property::text', text)
|
||||
end
|
||||
|
||||
--- Stop the keygrabber and mousegrabber
|
||||
function inputbox:stop()
|
||||
if (not self.akeygrabber) or (not self.akeygrabber.is_running) then return end
|
||||
self:emit_signal('stopped')
|
||||
self.akeygrabber.stop()
|
||||
end
|
||||
|
||||
function inputbox:focus()
|
||||
if (not self.akeygrabber) or (not self.akeygrabber.is_running) then
|
||||
akeygrabber.stop()
|
||||
self:run()
|
||||
end
|
||||
|
||||
self:connect_signal('button::press', function()
|
||||
if capi.mouse.current_widget ~= self then
|
||||
self:emit_signal('keygrabber::stop', '')
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- Init the inputbox and start the keygrabber
|
||||
function inputbox:run()
|
||||
if not self._private.text then self._private.text = '' end
|
||||
|
||||
-- Init the cursor position, but causes on refocus the cursor to move to the left
|
||||
local cursor_pos = self._private.cursor_pos or #self:get_text() + 1
|
||||
|
||||
-- Init and reset(when refocused) the highlight
|
||||
self._private.highlight = {}
|
||||
|
||||
self.akeygrabber = akeygrabber {
|
||||
autostart = true,
|
||||
start_callback = function()
|
||||
self:emit_signal('started')
|
||||
end,
|
||||
stop_callback = function(_, stop_key)
|
||||
if stop_key == 'Return' then
|
||||
self:emit_signal('submit', self:get_text(), stop_key)
|
||||
else
|
||||
self:emit_signal('stopped', stop_key)
|
||||
end
|
||||
end,
|
||||
stop_key = { 'Escape', 'Return' },
|
||||
keybindings = {
|
||||
--lShift, rShift = #50, #62
|
||||
--lControl, rControl = #37, #105
|
||||
akey {
|
||||
modifiers = { 'Shift' },
|
||||
key = 'Left', -- left
|
||||
on_press = function()
|
||||
if cursor_pos > 1 then
|
||||
local offset = (self._private.text:sub(cursor_pos - 1, cursor_pos - 1):wlen() == -1) and 1 or 0
|
||||
if not self._private.highlight.start_pos then
|
||||
self._private.highlight.start_pos = cursor_pos - 1
|
||||
end
|
||||
if not self._private.highlight.end_pos then
|
||||
self._private.highlight.end_pos = cursor_pos
|
||||
end
|
||||
|
||||
if self._private.highlight.start_pos < cursor_pos then
|
||||
self._private.highlight.end_pos = self._private.highlight.end_pos - 1
|
||||
else
|
||||
self._private.highlight.start_pos = self._private.highlight.start_pos
|
||||
end
|
||||
|
||||
cursor_pos = cursor_pos - 1
|
||||
end
|
||||
if cursor_pos < 1 then
|
||||
cursor_pos = 1
|
||||
elseif cursor_pos > #self._private.text + 1 then
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self._private.cursor_pos = cursor_pos
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', 'Shift', 'Left')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Shift' },
|
||||
key = 'Right', -- right
|
||||
on_press = function()
|
||||
if #self._private.text >= cursor_pos then
|
||||
if not self._private.highlight.end_pos then
|
||||
self._private.highlight.end_pos = cursor_pos - 1
|
||||
end
|
||||
if not self._private.highlight.start_pos then
|
||||
self._private.highlight.start_pos = cursor_pos
|
||||
end
|
||||
|
||||
if self._private.highlight.end_pos <= cursor_pos then
|
||||
self._private.highlight.end_pos = self._private.highlight.end_pos + 1
|
||||
else
|
||||
self._private.highlight.start_pos = self._private.highlight.start_pos + 1
|
||||
end
|
||||
cursor_pos = cursor_pos + 1
|
||||
if cursor_pos > #self._private.text + 1 then
|
||||
self._private.highlight = {}
|
||||
end
|
||||
end
|
||||
if cursor_pos < 1 then
|
||||
cursor_pos = 1
|
||||
elseif cursor_pos > #self._private.text + 1 then
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self._private.cursor_pos = cursor_pos
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', 'Shift', 'Right')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'a', -- a
|
||||
on_press = function()
|
||||
-- Mark the entire text
|
||||
self._private.highlight = {
|
||||
start_pos = 1,
|
||||
end_pos = #self._private.text,
|
||||
}
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', 'Control', 'a')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'v', -- v
|
||||
on_press = function()
|
||||
local sel = capi.selection()
|
||||
if sel then
|
||||
sel = sel:gsub('\n', '')
|
||||
if self._private.highlight and self._private.highlight.start_pos and
|
||||
self._private.highlight.end_pos then
|
||||
-- insert the text into the selected part
|
||||
local text_start = self._private.text:sub(1, self._private.highlight.start_pos - 1)
|
||||
local text_end = self._private.text:sub(self._private.highlight.end_pos + 1)
|
||||
self:set_text(text_start .. sel .. text_end)
|
||||
self._private.highlight = {}
|
||||
cursor_pos = #text_start + #sel + 1
|
||||
else
|
||||
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
|
||||
sel .. self._private.text:sub(cursor_pos))
|
||||
cursor_pos = cursor_pos + #sel
|
||||
end
|
||||
end
|
||||
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', 'Control', 'v')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'c', -- c
|
||||
on_press = function()
|
||||
--TODO
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'x', -- x
|
||||
on_press = function()
|
||||
--TODO
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'Left', -- left
|
||||
on_press = function()
|
||||
-- Find all spaces
|
||||
local spaces = {}
|
||||
local t, i = self._private.text, 0
|
||||
|
||||
while t:find('%s') do
|
||||
i = t:find('%s')
|
||||
table.insert(spaces, i)
|
||||
t = t:sub(1, i - 1) .. '-' .. t:sub(i + 1)
|
||||
end
|
||||
|
||||
local cp = 1
|
||||
for _, v in ipairs(spaces) do
|
||||
if (v < cursor_pos) then
|
||||
cp = v
|
||||
end
|
||||
end
|
||||
cursor_pos = cp
|
||||
if cursor_pos < 1 then
|
||||
cursor_pos = 1
|
||||
elseif cursor_pos > #self._private.text + 1 then
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', 'Control', 'Left')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'Right', -- right
|
||||
on_press = function()
|
||||
local next_space = self._private.text:sub(cursor_pos):find('%s')
|
||||
if next_space then
|
||||
cursor_pos = cursor_pos + next_space
|
||||
else
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
|
||||
if cursor_pos < 1 then
|
||||
cursor_pos = 1
|
||||
elseif cursor_pos > #self._private.text + 1 then
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', 'Control', 'Right')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'BackSpace', --BackSpace
|
||||
on_press = function()
|
||||
-- If text is highlighted delete that, else just delete the character to the left
|
||||
if self._private.highlight and self._private.highlight.start_pos and
|
||||
self._private.highlight.end_pos then
|
||||
local text_start = self._private.text:sub(1, self._private.highlight.start_pos - 1)
|
||||
local text_end = self._private.text:sub(self._private.highlight.end_pos + 1)
|
||||
self:set_text(text_start .. text_end)
|
||||
self._private.highlight = {}
|
||||
cursor_pos = #text_start + 1
|
||||
else
|
||||
if cursor_pos > 1 then
|
||||
local offset = (self._private.text:sub(cursor_pos - 1, cursor_pos - 1):wlen() == -1) and 1 or
|
||||
0
|
||||
self:set_text(self._private.text:sub(1, cursor_pos - 2 - offset) ..
|
||||
self._private.text:sub(cursor_pos))
|
||||
cursor_pos = cursor_pos - 1 - offset
|
||||
end
|
||||
end
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', nil, 'BackSpace')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Delete', --delete
|
||||
on_press = function()
|
||||
-- If text is highlighted delete that, else just delete the character to the right
|
||||
if self._private.highlight and self._private.highlight.start_pos and
|
||||
self._private.highlight.end_pos then
|
||||
local text_start = self._private.text:sub(1, self._private.highlight.start_pos - 1)
|
||||
local text_end = self._private.text:sub(self._private.highlight.end_pos + 1)
|
||||
self:set_text(text_start .. text_end)
|
||||
self._private.highlight = {}
|
||||
cursor_pos = #text_start + 1
|
||||
else
|
||||
if cursor_pos <= #self._private.text then
|
||||
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
|
||||
self._private.text:sub(cursor_pos + 1))
|
||||
end
|
||||
end
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', nil, 'Delete')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Left', --left
|
||||
on_press = function()
|
||||
-- Move cursor ro the left
|
||||
if cursor_pos > 1 then
|
||||
cursor_pos = cursor_pos - 1
|
||||
end
|
||||
self._private.highlight = {}
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Right', --right
|
||||
on_press = function()
|
||||
-- Move cursor to the right
|
||||
if cursor_pos <= #self._private.text then
|
||||
cursor_pos = cursor_pos + 1
|
||||
end
|
||||
self._private.highlight = {}
|
||||
end,
|
||||
},
|
||||
--self.keybindings
|
||||
},
|
||||
keypressed_callback = function(_, modifiers, key)
|
||||
if modifiers[1] == 'Shift' then
|
||||
if key:wlen() == 1 then
|
||||
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
|
||||
string.upper(key) .. self._private.text:sub(cursor_pos))
|
||||
cursor_pos = cursor_pos + #key
|
||||
end
|
||||
elseif modifiers[1] == 'Mod2' or '' then
|
||||
if key:wlen() == 1 then
|
||||
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
|
||||
key .. self._private.text:sub(cursor_pos))
|
||||
cursor_pos = cursor_pos + #key
|
||||
end
|
||||
end
|
||||
|
||||
if cursor_pos < 1 then
|
||||
cursor_pos = 1
|
||||
elseif cursor_pos > #self._private.text + 1 then
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', modifiers, key)
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
--[[
|
||||
take the text and cursor position and figure out which character is next
|
||||
if mx is greater than lx then the right character is the next character
|
||||
if mx is less than lx then the left character is the next character
|
||||
|
||||
calculate the delta between mx and lx, if the delta is greater than the next
|
||||
character increase or decrease the cursor position by 1 (depends if the delta is positive or negative)
|
||||
and set the lx = mx
|
||||
|
||||
return 1 if advanced to the right, -1 if advanced to the left, 0 if not advanced; and the new lx
|
||||
]]
|
||||
function inputbox:advanced_by_character(mx, lx)
|
||||
local delta = mx - lx
|
||||
local character
|
||||
if delta < 0 then
|
||||
character = self._private.text:sub(self._private.cursor_pos + 1, self._private.cursor_pos + 1)
|
||||
else
|
||||
character = self._private.text:sub(self._private.cursor_pos - 1, self._private.cursor_pos - 1)
|
||||
end
|
||||
|
||||
--local character = (self._private.text:sub(self._private.cursor_pos + 1, self._private.cursor_pos + 1) and (delta < 0)) or self._private.text:sub(self._private.cursor_pos - 1, self._private.cursor_pos - 1)
|
||||
if character then
|
||||
local cr = cairo.Context(cairo.ImageSurface(cairo.Format.ARGB32, 1, 1))
|
||||
cr:select_font_face(self.font, cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL)
|
||||
cr:set_font_size(self.font_size)
|
||||
local extents = cr:text_extents(character)
|
||||
if math.abs(delta) >= extents.x_advance then
|
||||
self._private.cursor_pos = self._private.cursor_pos + (((delta > 0) and 1) or -1)
|
||||
lx = mx
|
||||
return (((delta > 0) and 1) or -1), lx
|
||||
end
|
||||
end
|
||||
return 0, lx
|
||||
end
|
||||
|
||||
--- Creates a new inputbox widget
|
||||
-- @tparam table args Arguments for the inputbox widget
|
||||
-- @tparam string args.text The text to display in the inputbox
|
||||
-- @tparam[opt=beautiful.fg_normal] string args.fg Text foreground color
|
||||
-- @tparam[opt=beautiful.border_focus] string args.border_focus_color Border color when focused
|
||||
-- @tparam[opt=""] string args.placeholder_text placeholder text to be shown when not focused and
|
||||
-- @tparam[opt=beautiful.inputbox_placeholder_fg] string args.placeholder_fg placeholder text foreground color
|
||||
-- @tparam[opt=beautiful.inputbox_cursor_bg] string args.cursor_bg Cursor background color
|
||||
-- @tparam[opt=beautiful.inputbox_cursor_fg] string args.cursor_fg Cursor foreground color
|
||||
-- @tparam[opt=beautiful.inputbox_highlight_bg] string args.highlight_bg Highlight background color
|
||||
-- @tparam[opt=beautiful.inputbox_highlight_fg] string args.highlight_fg Highlight foreground color
|
||||
-- @treturn awful.widget.inputbox The inputbox widget.
|
||||
-- @constructorfct awful.widget.inputbox
|
||||
function inputbox.new(args)
|
||||
args = args or {}
|
||||
|
||||
-- directly pass a possible default text(this is not meant to be a hint)
|
||||
local w = imagebox()
|
||||
|
||||
--gtable.crush(w, args)
|
||||
gtable.crush(w, inputbox, true)
|
||||
w._private = {}
|
||||
|
||||
w._private.text = args.text or ''
|
||||
w.font_size = 24
|
||||
w.font = User_config.font.regular
|
||||
w._private.cursor_pos = args.cursor_pos
|
||||
w._private.highlight = args.highlight
|
||||
|
||||
w.p = apopup {
|
||||
widget = {
|
||||
{
|
||||
image = w:draw_text_surface(),
|
||||
resize = false,
|
||||
valign = 'bottom',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
id = 'text_image',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = 20,
|
||||
},
|
||||
bg = '#212121',
|
||||
visible = true,
|
||||
screen = 1,
|
||||
placement = aplacement.centered,
|
||||
}
|
||||
|
||||
w.p.widget:get_children_by_id('text_image')[1]:buttons(gtable.join {
|
||||
abutton({}, 1, function()
|
||||
-- Get the mouse coordinates realative to the widget
|
||||
local x, y = mouse.coords().x - p.x - 20, mouse.coords().y - p.y - 20 -- 20 is the margin on either side
|
||||
p.widget:get_children_by_id('text_image')[1].image = w:draw_text_surface(x, false)
|
||||
w.highlight = { start_pos = w.cursor_pos, end_pos = w.cursor_pos }
|
||||
p.widget:get_children_by_id('text_image')[1].image = w:draw_text_surface(x, false)
|
||||
if not mousegrabber.isrunning() then
|
||||
local last_x, advanced, cursor_pos, mx = x, nil, w.cursor_pos, nil
|
||||
mousegrabber.run(function(m)
|
||||
mx = m.x - p.x - 20
|
||||
if (math.abs(mx - x) > 5) then
|
||||
-- Returns 1 if the mouse has advanced to the right, -1 if it has advanced to the left
|
||||
advanced, last_x = w:advanced_by_character(mx, last_x)
|
||||
if advanced == 1 then
|
||||
print(cursor_pos, w.highlight.start_pos, w.highlight.end_pos)
|
||||
if cursor_pos <= w.highlight.start_pos then
|
||||
if w.highlight.end_pos < #w._private.text then
|
||||
w.highlight.end_pos = w.highlight.end_pos + 1
|
||||
end
|
||||
else
|
||||
w.highlight.start_pos = w.highlight.start_pos + 1
|
||||
end
|
||||
p.widget:get_children_by_id('text_image')[1].image = w:draw_text_surface(x, true)
|
||||
print(w.highlight.start_pos, w.highlight.end_pos)
|
||||
elseif advanced == -1 then
|
||||
if cursor_pos >= w.highlight.end_pos then
|
||||
if w.highlight.start_pos > 1 then
|
||||
w.highlight.start_pos = w.highlight.start_pos - 1
|
||||
end
|
||||
else
|
||||
w.highlight.end_pos = w.highlight.end_pos - 1
|
||||
end
|
||||
p.widget:get_children_by_id('text_image')[1].image = w:draw_text_surface(x, true)
|
||||
print(w.highlight.start_pos, w.highlight.end_pos)
|
||||
end
|
||||
end
|
||||
|
||||
return m.buttons[1]
|
||||
end, 'xterm')
|
||||
end
|
||||
w:run()
|
||||
end),
|
||||
})
|
||||
|
||||
--w.font = args.font or beautiful.font
|
||||
|
||||
--w.keybindings = args.keybindings or {}
|
||||
--w.hint_text = args.hint_text
|
||||
|
||||
--w.markup = args.text or text_with_cursor('', 1, w)
|
||||
return w
|
||||
end
|
||||
|
||||
function inputbox.mt:__call(...)
|
||||
return inputbox.new(...)
|
||||
end
|
||||
|
||||
return setmetatable(inputbox, inputbox.mt)
|
||||
485
awesome/src/modules/inputbox/new.lua
Normal file
485
awesome/src/modules/inputbox/new.lua
Normal file
@@ -0,0 +1,485 @@
|
||||
local Pango = require('lgi').Pango
|
||||
local PangoCairo = require('lgi').PangoCairo
|
||||
local abutton = require('awful.button')
|
||||
local akey = require('awful.key')
|
||||
local akeygrabber = require('awful.keygrabber')
|
||||
local aplacement = require('awful.placement')
|
||||
local apopup = require('awful.popup')
|
||||
local base = require('wibox.widget.base')
|
||||
local beautiful = require('beautiful')
|
||||
local cairo = require('lgi').cairo
|
||||
local gobject = require('gears.object')
|
||||
local gstring = require('gears.string')
|
||||
local gsurface = require('gears.surface')
|
||||
local gtable = require('gears.table')
|
||||
local gtimer = require('gears.timer')
|
||||
local imagebox = require('wibox.widget.imagebox')
|
||||
local setmetatable = setmetatable
|
||||
local textbox = require('wibox.widget.textbox')
|
||||
local wibox = require('wibox')
|
||||
local dpi = beautiful.xresources.apply_dpi
|
||||
|
||||
local capi = {
|
||||
selection = selection,
|
||||
mousegrabber = mousegrabber,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
local inputbox = {}
|
||||
|
||||
local function get_text_extent(text, font, font_size, args)
|
||||
local surface = cairo.ImageSurface(cairo.Format.ARGB32, 0, 0)
|
||||
local cr = cairo.Context(surface)
|
||||
cr:select_font_face(font, args)
|
||||
cr:set_font_size(font_size)
|
||||
return cr:text_extents(text)
|
||||
end
|
||||
|
||||
function inputbox.draw_text(self)
|
||||
local text = self:get_text()
|
||||
local highlight = self:get_highlight()
|
||||
local fg_color = { 1, 1, 1 }
|
||||
local cursor_color = { 1, 1, 1, 1 }
|
||||
|
||||
if text == '' then
|
||||
fg_color = { 0.2, 0.2, 0.2 }
|
||||
-- Silently change the text, it will be changed back after it is drawn
|
||||
self._private.layout:set_text(self._private.text_hint)
|
||||
end
|
||||
|
||||
local _, pango_extent = self._private.layout:get_extents()
|
||||
|
||||
local surface = cairo.ImageSurface(cairo.Format.ARGB32, (pango_extent.width / Pango.SCALE) + pango_extent.x, (pango_extent.height / Pango.SCALE) + pango_extent.y)
|
||||
local cr = cairo.Context(surface)
|
||||
|
||||
-- Draw highlight
|
||||
if (highlight.start_pos ~= 0) or (highlight.end_pos ~= 0) then
|
||||
cr:set_source_rgb(0, 0, 1)
|
||||
local txt = text:sub(self:get_highlight().start_pos + 1, self:get_highlight().end_pos)
|
||||
cr:rectangle(
|
||||
cr:text_extents(text:sub(0, self:get_highlight().start_pos)).x_advance,
|
||||
pango_extent.y / Pango.SCALE,
|
||||
cr:text_extents(txt).width,
|
||||
pango_extent.height / Pango.SCALE
|
||||
)
|
||||
cr:fill()
|
||||
end
|
||||
|
||||
-- Draw text
|
||||
PangoCairo.update_layout(cr, self._private.layout)
|
||||
cr:set_source_rgba(1, 1, 1, 1)
|
||||
cr:move_to(0, 0)
|
||||
PangoCairo.show_layout(cr, self._private.layout)
|
||||
|
||||
-- Draw cursor
|
||||
cr:set_source_rgba(table.unpack(cursor_color))
|
||||
local cursor = self:get_cursor_pos()
|
||||
cr:rectangle(
|
||||
cursor.x / Pango.SCALE,
|
||||
cursor.y / Pango.SCALE,
|
||||
2,
|
||||
cursor.height / Pango.SCALE)
|
||||
cr:fill()
|
||||
|
||||
self.widget:set_image(surface)
|
||||
return surface
|
||||
end
|
||||
|
||||
function inputbox:start_keygrabber()
|
||||
self.akeygrabber = akeygrabber {
|
||||
autostart = true,
|
||||
stop_key = { 'Escape', 'Return' },
|
||||
start_callback = function()
|
||||
end,
|
||||
stop_callback = function()
|
||||
end,
|
||||
keybindings = {
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'BackSpace',
|
||||
on_press = function()
|
||||
local hl = self:get_highlight()
|
||||
local text = self:get_text()
|
||||
local cursor_pos = self:get_cursor_index()
|
||||
if hl.end_pos ~= hl.start_pos then
|
||||
self:set_text(text:sub(0, hl.start_pos) .. text:sub(hl.end_pos + 1, #text))
|
||||
self:set_cursor_pos(hl.start_pos)
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
else
|
||||
self:set_text(text:sub(1, cursor_pos - 1) .. text:sub(cursor_pos + 1))
|
||||
self:set_cursor_pos(cursor_pos - 1)
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Delete',
|
||||
on_press = function()
|
||||
local hl = self:get_highlight()
|
||||
local text = self:get_text()
|
||||
local cursor_pos = self:get_cursor_index()
|
||||
if hl.end_pos ~= hl.start_pos then
|
||||
self:set_text(text:sub(0, hl.start_pos) .. text:sub(hl.end_pos + 1, #text))
|
||||
self:set_cursor_pos(hl.start_pos)
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
else
|
||||
self:set_text(text:sub(1, cursor_pos) .. text:sub(cursor_pos + 2, #text))
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Left',
|
||||
on_press = function()
|
||||
self:set_cursor_pos(self:get_cursor_index() - 1)
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Right',
|
||||
on_press = function()
|
||||
self:set_cursor_pos(self:get_cursor_index() + 1)
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Home',
|
||||
on_press = function()
|
||||
self:set_cursor_pos(0)
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'End',
|
||||
on_press = function()
|
||||
self:set_cursor_pos(#self:get_text())
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Shift' },
|
||||
key = 'Left',
|
||||
on_press = function()
|
||||
local cursor_pos = self:get_cursor_pos()
|
||||
local hl = self:get_highlight()
|
||||
if cursor_pos == hl.start_pos then
|
||||
self:set_cursor_pos(cursor_pos - 1)
|
||||
self:set_highlight { start_pos = self:get_cursor_pos(), end_pos = hl.end_pos }
|
||||
elseif cursor_pos == hl.end_pos then
|
||||
self:set_cursor_pos(cursor_pos - 1)
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = self:get_cursor_pos() }
|
||||
else
|
||||
if (hl.start_pos ~= cursor_pos) and (hl.end_pos ~= cursor_pos) then
|
||||
self:set_highlight { start_pos = cursor_pos, end_pos = cursor_pos }
|
||||
hl = self:get_highlight()
|
||||
self:set_cursor_pos(cursor_pos - 1)
|
||||
self:set_highlight { start_pos = self:get_cursor_pos(), end_pos = hl.end_pos }
|
||||
end
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Shift' },
|
||||
key = 'Right',
|
||||
on_press = function()
|
||||
local cursor_pos = self:get_cursor_pos()
|
||||
local hl = self:get_highlight()
|
||||
if cursor_pos == hl.end_pos then
|
||||
self:set_cursor_pos(cursor_pos + 1)
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = self:get_cursor_pos() }
|
||||
elseif cursor_pos == hl.start_pos then
|
||||
self:set_cursor_pos(cursor_pos + 1)
|
||||
self:set_highlight { start_pos = self:get_cursor_pos(), end_pos = hl.end_pos }
|
||||
else
|
||||
if (hl.start_pos ~= cursor_pos) and (hl.end_pos ~= cursor_pos) then
|
||||
self:set_highlight { start_pos = cursor_pos, end_pos = cursor_pos }
|
||||
hl = self:get_highlight()
|
||||
self:set_cursor_pos(cursor_pos + 1)
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = self:get_cursor_pos() }
|
||||
end
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'a',
|
||||
on_press = function()
|
||||
self:set_highlight { start_pos = 0, end_pos = #self:get_text() }
|
||||
self:set_cursor_pos(#self:get_text() - 1)
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'c',
|
||||
on_press = function()
|
||||
local hl = self:get_highlight()
|
||||
if hl.start_pos ~= hl.end_pos then
|
||||
local text = self:get_text():sub(hl.start_pos, hl.end_pos)
|
||||
--TODO:self:copy_to_clipboard(text)
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'v',
|
||||
on_press = function()
|
||||
local hl = self:get_highlight()
|
||||
local selection = capi.selection()
|
||||
if hl.start_pos ~= hl.end_pos then
|
||||
self:set_text(self:get_text():sub(1, hl.start_pos) .. selection .. self:get_text():sub(hl.end_pos + 1, #self:get_text()))
|
||||
self:set_cursor_pos(hl.start_pos + #selection)
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
else
|
||||
self:set_text(self:get_text():sub(1, self:get_cursor_pos()) .. selection .. self:get_text():sub(self:get_cursor_pos() + 1, #self:get_text()))
|
||||
self:set_cursor_pos(self:get_cursor_pos() + #selection)
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'x',
|
||||
on_press = function()
|
||||
--TODO
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'Right',
|
||||
on_press = function()
|
||||
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'Left',
|
||||
on_press = function()
|
||||
|
||||
end,
|
||||
},
|
||||
},
|
||||
keypressed_callback = function(_, mod, key)
|
||||
local text = self:get_text()
|
||||
local cursor_pos = self:get_cursor_index()
|
||||
if (mod[1] == 'Mod2' or '') and (key:wlen() == 1) then
|
||||
self:set_text(text:sub(1, cursor_pos) .. key .. text:sub(cursor_pos + 1, #text))
|
||||
self:set_cursor_pos(cursor_pos + #key)
|
||||
elseif (mod[1] == 'Shift') and (key:wlen() == 1) then
|
||||
self:set_text(text:sub(1, cursor_pos) .. key:upper() .. text:sub(cursor_pos + 1, #text))
|
||||
self:set_cursor_pos(cursor_pos + #key)
|
||||
end
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
--[[ function inputbox:advanced_by_character(mx, last_x)
|
||||
local delta = mx - last_x
|
||||
local character
|
||||
local text = self:get_text()
|
||||
local cursor_pos = self:get_cursor_pos()
|
||||
if delta < 0 then
|
||||
character = text:sub(cursor_pos + 1, cursor_pos + 1)
|
||||
else
|
||||
character = text:sub(cursor_pos - 1, cursor_pos - 1)
|
||||
end
|
||||
|
||||
if character then
|
||||
local extents = get_text_extent(character, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
if math.abs(delta) >= extents.x_advance then
|
||||
self:set_cursor_pos(cursor_pos + (((delta > 0) and 1) or -1))
|
||||
last_x = mx
|
||||
return (((delta > 0) and 1) or -1), last_x
|
||||
end
|
||||
end
|
||||
return 0, last_x
|
||||
end ]]
|
||||
|
||||
function inputbox:start_mousegrabber(x, y)
|
||||
--[[ if not mousegrabber.isrunning() then
|
||||
local last_x, advanced, cursor_pos, mx = x, nil, self:get_cursor_pos(), nil
|
||||
local hl = self:get_highlight()
|
||||
self:set_highlight { start_pos = cursor_pos, end_pos = cursor_pos }
|
||||
local text = self:get_text()
|
||||
mousegrabber.run(function(m)
|
||||
mx = m.x
|
||||
if (math.abs(mx - x) > 5) then
|
||||
advanced, last_x = self:advanced_by_character(mx, last_x)
|
||||
if advanced == 1 then
|
||||
if cursor_pos <= hl.start_pos then
|
||||
if hl.end_pos < #text then
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = hl.end_pos + 1 }
|
||||
end
|
||||
else
|
||||
self:set_highlight { start_pos = hl.start_pos + 1, end_pos = hl.end_pos }
|
||||
end
|
||||
elseif advanced == -1 then
|
||||
if cursor_pos >= hl.end_pos then
|
||||
if hl.start_pos > 1 then
|
||||
self:set_highlight { start_pos = hl.start_pos - 1, end_pos = hl.end_pos }
|
||||
end
|
||||
else
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = hl.end_pos - 1 }
|
||||
end
|
||||
end
|
||||
end
|
||||
hl = self:get_highlight()
|
||||
return m.buttons[1]
|
||||
end, 'xterm')
|
||||
end ]]
|
||||
if not mousegrabber.isrunning() then
|
||||
local index, _ = self._private.layout:xy_to_index(x * Pango.SCALE, y * Pango.SCALE)
|
||||
|
||||
if not index then return end
|
||||
|
||||
self:set_cursor_pos(index)
|
||||
-- Remove highlight, but also prepare its position (same pos = no highlight)
|
||||
self:set_highlight { start_pos = index, end_pos = index }
|
||||
|
||||
local text = self:get_text()
|
||||
local cursor_pos = self:get_cursor_pos()
|
||||
local hl = self:get_highlight()
|
||||
|
||||
mousegrabber.run(function(m)
|
||||
index, _ = self._private.layout:xy_to_index(m.x * Pango.SCALE, m.y * Pango.SCALE)
|
||||
|
||||
if not index then return end
|
||||
|
||||
if math.abs(index - cursor_pos) == 1 then
|
||||
if cursor_pos <= hl.start_pos then
|
||||
if hl.end_pos < #text then
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = hl.end_pos + 1 }
|
||||
end
|
||||
else
|
||||
self:set_highlight { start_pos = hl.start_pos + 1, end_pos = hl.end_pos }
|
||||
end
|
||||
elseif math.abs(index - cursor_pos) == -1 then
|
||||
if cursor_pos >= hl.end_pos then
|
||||
if hl.start_pos > 1 then
|
||||
self:set_highlight { start_pos = hl.start_pos - 1, end_pos = hl.end_pos }
|
||||
end
|
||||
else
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = hl.end_pos - 1 }
|
||||
end
|
||||
end
|
||||
|
||||
if index ~= cursor_pos then
|
||||
self:set_cursor_pos(index)
|
||||
end
|
||||
|
||||
return m.buttons[1]
|
||||
end, 'xterm')
|
||||
end
|
||||
end
|
||||
|
||||
function inputbox:set_cursor_pos_from_mouse(x, y)
|
||||
-- When setting the cursor position, trailing is not needed as its handled by the setter
|
||||
local index, _ = self._private.layout:xy_to_index(x * Pango.SCALE, y * Pango.SCALE)
|
||||
if not index then return end
|
||||
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
self:set_cursor_pos(index)
|
||||
end
|
||||
|
||||
function inputbox:get_text()
|
||||
return self._private.layout:get_text()
|
||||
end
|
||||
|
||||
function inputbox:set_text(text)
|
||||
if self:get_text() == text then return end
|
||||
|
||||
local attributes, parsed = Pango.parse_markup(text, -1, 0)
|
||||
|
||||
if not attributes then return parsed.message or tostring(parsed) end
|
||||
|
||||
self._private.layout:set_text(parsed, string.len(parsed))
|
||||
self._private.layout:set_attributes(attributes)
|
||||
|
||||
self.draw_text(self)
|
||||
end
|
||||
|
||||
function inputbox:get_cursor_pos()
|
||||
return self._private.layout:get_cursor_pos(self._private.cursor_pos.index)
|
||||
end
|
||||
|
||||
function inputbox:get_cursor_index()
|
||||
return self._private.cursor_pos.index
|
||||
end
|
||||
|
||||
function inputbox:set_cursor_pos(cursor_pos)
|
||||
-- moving only moved one character set, to move it multiple times we need to loop as long as the difference to the new cursor isn't 0
|
||||
if not cursor_pos or (cursor_pos < 0) or (cursor_pos >= #self:get_text()) then return end
|
||||
while (cursor_pos - self._private.cursor_pos.index) ~= 0 do
|
||||
self._private.cursor_pos.index, self._private.cursor_pos.trailing = self._private.layout:move_cursor_visually(
|
||||
true, self._private.cursor_pos.index,
|
||||
self._private.cursor_pos.trailing,
|
||||
cursor_pos - self._private.cursor_pos.index
|
||||
)
|
||||
end
|
||||
|
||||
self.draw_text(self)
|
||||
end
|
||||
|
||||
function inputbox:get_highlight()
|
||||
return self._private.highlight
|
||||
end
|
||||
|
||||
function inputbox:set_highlight(highlight)
|
||||
self._private.highlight = highlight
|
||||
self.draw_text(self)
|
||||
end
|
||||
|
||||
function inputbox:focus()
|
||||
|
||||
end
|
||||
|
||||
function inputbox:unfocus()
|
||||
|
||||
end
|
||||
|
||||
function inputbox.new(args)
|
||||
local ret = gobject { enable_properties = true }
|
||||
args.text = args.text .. '\n'
|
||||
gtable.crush(ret, inputbox)
|
||||
|
||||
ret._private = {}
|
||||
ret._private.context = PangoCairo.font_map_get_default():create_context()
|
||||
ret._private.layout = Pango.Layout.new(ret._private.context)
|
||||
|
||||
ret.font_size = 24
|
||||
ret.font = 'JetBrainsMono Nerd Font, ' .. 24
|
||||
ret._private.layout:set_font_description(Pango.FontDescription.from_string('JetBrainsMono Nerd Font 16'))
|
||||
|
||||
ret._private.text_hint = args.text_hint or ''
|
||||
ret._private.cursor_pos = {
|
||||
index = args.cursor_pos or 0,
|
||||
trailing = 0,
|
||||
}
|
||||
ret._private.highlight = args.highlight or {
|
||||
start_pos = 0,
|
||||
end_pos = 0,
|
||||
}
|
||||
|
||||
ret.widget = imagebox(nil, false)
|
||||
|
||||
ret.widget:connect_signal('button::press', function(_, x, y, button)
|
||||
if button == 1 then
|
||||
ret:set_cursor_pos_from_mouse(x, y)
|
||||
--ret:start_mousegrabber(x, y)
|
||||
ret:start_keygrabber()
|
||||
end
|
||||
end)
|
||||
|
||||
ret:set_text(args.text or '')
|
||||
--ret:set_cursor_pos(ret._private.cursor_pos)
|
||||
ret:set_highlight(ret._private.highlight)
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
return setmetatable(inputbox, {
|
||||
__call = function(_, ...)
|
||||
return inputbox.new(...)
|
||||
end,
|
||||
})
|
||||
@@ -3,44 +3,45 @@
|
||||
------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require("awful.button")
|
||||
local awidget = require("awful.widget")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears").table
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local gcolor = require("gears").color
|
||||
local lgi = require("lgi")
|
||||
local wibox = require("wibox")
|
||||
local base = require("wibox.widget.base")
|
||||
local abutton = require('awful.button')
|
||||
local awidget = require('awful.widget')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gtable = require('gears').table
|
||||
local gfilesystem = require('gears').filesystem
|
||||
local gcolor = require('gears').color
|
||||
local lgi = require('lgi')
|
||||
local wibox = require('wibox')
|
||||
local base = require('wibox.widget.base')
|
||||
local NM = lgi.NM
|
||||
|
||||
-- Third party libs
|
||||
local dbus_proxy = require("src.lib.lua-dbus_proxy.src.dbus_proxy")
|
||||
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
|
||||
|
||||
-- Own libs
|
||||
local ap_form = require("src.modules.network_controller.ap_form")
|
||||
local cm = require("src.modules.context_menu.init")
|
||||
local ap_form = require('src.modules.network_controller.ap_form')
|
||||
local cm = require('src.modules.context_menu.init')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/network/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/'
|
||||
|
||||
local access_point = { mt = {} }
|
||||
|
||||
local function flags_to_security(flags, wpa_flags, rsn_flags)
|
||||
local str = ""
|
||||
local str = ''
|
||||
if flags == 1 and wpa_flags == 0 and rsn_flags == 0 then
|
||||
str = str .. " WEP"
|
||||
str = str .. ' WEP'
|
||||
end
|
||||
if wpa_flags ~= 0 then
|
||||
str = str .. " WPA1"
|
||||
str = str .. ' WPA1'
|
||||
end
|
||||
if not rsn_flags ~= 0 then
|
||||
str = str .. " WPA2"
|
||||
str = str .. ' WPA2'
|
||||
end
|
||||
if wpa_flags == 512 or rsn_flags == 512 then
|
||||
str = str .. " 802.1X"
|
||||
str = str .. ' 802.1X'
|
||||
end
|
||||
|
||||
return (str:gsub("^%s", ""))
|
||||
return (str:gsub('^%s', ''))
|
||||
end
|
||||
|
||||
function access_point:get_access_point_connections(ssid)
|
||||
@@ -50,9 +51,9 @@ function access_point:get_access_point_connections(ssid)
|
||||
for _, connection_path in ipairs(connections) do
|
||||
local NetworkManagerSettingsConnection = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.Settings.Connection",
|
||||
path = connection_path
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.Settings.Connection',
|
||||
path = connection_path,
|
||||
}
|
||||
|
||||
if NetworkManagerSettingsConnection.Filename:find(ssid) then
|
||||
@@ -66,39 +67,39 @@ end
|
||||
function access_point:create_profile(ap, password, auto_connect)
|
||||
local s_wsec = {}
|
||||
local security = flags_to_security(ap.Flags, ap.WpaFlags, ap.RsnFlags)
|
||||
if security ~= "" then
|
||||
if security:match("WPA") then
|
||||
s_wsec["key-mgmt"] = lgi.GLib.Variant("s", "wpa-psk")
|
||||
s_wsec["auth-alg"] = lgi.GLib.Variant("s", "open")
|
||||
s_wsec["psk"] = lgi.GLib.Variant("s", password)
|
||||
if security ~= '' then
|
||||
if security:match('WPA') then
|
||||
s_wsec['key-mgmt'] = lgi.GLib.Variant('s', 'wpa-psk')
|
||||
s_wsec['auth-alg'] = lgi.GLib.Variant('s', 'open')
|
||||
s_wsec['psk'] = lgi.GLib.Variant('s', password)
|
||||
else
|
||||
s_wsec["key-mgmt"] = lgi.GLib.Variant("s", "None")
|
||||
s_wsec["wep-key-type"] = lgi.GLib.Variant("s", NM.WepKeyType.PASSPHRASE)
|
||||
s_wsec["wep-key0"] = lgi.GLib.Variant("s", password)
|
||||
s_wsec['key-mgmt'] = lgi.GLib.Variant('s', 'None')
|
||||
s_wsec['wep-key-type'] = lgi.GLib.Variant('s', NM.WepKeyType.PASSPHRASE)
|
||||
s_wsec['wep-key0'] = lgi.GLib.Variant('s', password)
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
["connection"] = {
|
||||
['connection'] = {
|
||||
-- ["interface-name"] = lgi.GLib.Variant("s", ap.device_interface),
|
||||
["uuid"] = lgi.GLib.Variant("s", string.gsub('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', '[xy]', function(c)
|
||||
['uuid'] = lgi.GLib.Variant('s', string.gsub('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', '[xy]', function(c)
|
||||
local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
|
||||
return string.format('%x', v)
|
||||
end)),
|
||||
["id"] = lgi.GLib.Variant("s", NM.utils_ssid_to_utf8(ap.Ssid)),
|
||||
["type"] = lgi.GLib.Variant("s", "802-11-wireless"),
|
||||
["autoconnect"] = lgi.GLib.Variant("b", auto_connect),
|
||||
['id'] = lgi.GLib.Variant('s', NM.utils_ssid_to_utf8(ap.Ssid)),
|
||||
['type'] = lgi.GLib.Variant('s', '802-11-wireless'),
|
||||
['autoconnect'] = lgi.GLib.Variant('b', auto_connect),
|
||||
},
|
||||
["ipv4"] = {
|
||||
["method"] = lgi.GLib.Variant("s", "auto")
|
||||
['ipv4'] = {
|
||||
['method'] = lgi.GLib.Variant('s', 'auto'),
|
||||
},
|
||||
["ipv6"] = {
|
||||
["method"] = lgi.GLib.Variant("s", "auto"),
|
||||
['ipv6'] = {
|
||||
['method'] = lgi.GLib.Variant('s', 'auto'),
|
||||
},
|
||||
["802-11-wireless"] = {
|
||||
["mode"] = lgi.GLib.Variant("s", "infrastructure"),
|
||||
['802-11-wireless'] = {
|
||||
['mode'] = lgi.GLib.Variant('s', 'infrastructure'),
|
||||
},
|
||||
["802-11-wireless-security"] = s_wsec
|
||||
['802-11-wireless-security'] = s_wsec,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -113,26 +114,25 @@ function access_point:connect(ap, password, auto_connect)
|
||||
if #connections == 0 then
|
||||
self.NetworkManager:AddAndActivateConnectionAsync(function(proxy, context, success, fail)
|
||||
if fail ~= nil then
|
||||
print("Error: " .. tostring(fail), tostring(fail.code))
|
||||
self:emit_signal("NetworkManager::failed", tostring(fail), tostring(fail.code))
|
||||
self:emit_signal('NetworkManager::failed', tostring(fail), tostring(fail.code))
|
||||
return
|
||||
end
|
||||
|
||||
self:emit_signal("NetworkManager::connected", success)
|
||||
end, { call_id = "my-id" }, profile, self.NetworkManagerDevice.object_path,
|
||||
self:emit_signal('NetworkManager::connected', success)
|
||||
end, { call_id = 'my-id' }, profile, self.NetworkManagerDevice.object_path,
|
||||
self.NetworkManagerAccessPoint.object_path)
|
||||
--88ALYLNxo9Kk*RwRxMfN
|
||||
else
|
||||
connections[1]:Update(profile)
|
||||
self.NetworkManager:ActivateConnectionAsync(function(proxy, context, success, failure)
|
||||
if failure then
|
||||
self:emit_signal("NM::AccessPointFailed", tostring(failure))
|
||||
self:emit_signal('NM::AccessPointFailed', tostring(failure))
|
||||
return
|
||||
end
|
||||
|
||||
self:emit_signal("NM::AccessPointConnected", NM.utils_ssid_to_utf8(ap.Ssid))
|
||||
self:emit_signal('NM::AccessPointConnected', NM.utils_ssid_to_utf8(ap.Ssid))
|
||||
end,
|
||||
{ call_id = "my-id" }, connections[1].object_path, self.NetworkManagerDevice.object_path,
|
||||
{ call_id = 'my-id' }, connections[1].object_path, self.NetworkManagerDevice.object_path,
|
||||
self.NetworkManagerAccessPoint.object_path)
|
||||
end
|
||||
end
|
||||
@@ -156,9 +156,9 @@ function access_point.new(args)
|
||||
|
||||
local ssid_text = awidget.inputbox {
|
||||
text = NM.utils_ssid_to_utf8(args.NetworkManagerAccessPoint.Ssid) or
|
||||
args.NetworkManagerAccessPoint.hw_address or "Unknown",
|
||||
halign = "left",
|
||||
valign = "center",
|
||||
args.NetworkManagerAccessPoint.hw_address or 'Unknown',
|
||||
halign = 'left',
|
||||
valign = 'center',
|
||||
}
|
||||
|
||||
local ret = base.make_widget_from_value(wibox.widget {
|
||||
@@ -168,84 +168,86 @@ function access_point.new(args)
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(
|
||||
icondir .. "wifi-strength-" .. math.floor(args.NetworkManagerAccessPoint.Strength / 25) + 1 .. ".svg",
|
||||
icondir .. 'wifi-strength-' .. math.floor(args.NetworkManagerAccessPoint.Strength / 25) + 1 .. '.svg',
|
||||
Theme_config.network_manager.access_point.icon_color),
|
||||
id = "icon",
|
||||
id = 'icon',
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
forced_width = dpi(24),
|
||||
forced_height = dpi(24),
|
||||
widget = wibox.widget.imagebox
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
id = "icon_container",
|
||||
strategy = "max",
|
||||
id = 'icon_container',
|
||||
strategy = 'max',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
{
|
||||
ssid_text,
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = dpi(300),
|
||||
id = "alias"
|
||||
id = 'alias',
|
||||
},
|
||||
width = dpi(260),
|
||||
height = dpi(40),
|
||||
strategy = "max",
|
||||
widget = wibox.container.constraint
|
||||
strategy = 'max',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{ -- Spacing
|
||||
forced_width = dpi(10),
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "con",
|
||||
id = 'con',
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
forced_width = dpi(24),
|
||||
forced_height = dpi(24),
|
||||
widget = wibox.widget.imagebox
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
id = "place",
|
||||
strategy = "max",
|
||||
id = 'place',
|
||||
strategy = 'max',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
id = "margin",
|
||||
id = 'margin',
|
||||
margins = dpi(2),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "margin0",
|
||||
id = 'margin0',
|
||||
margin = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "device_layout",
|
||||
layout = wibox.layout.align.horizontal
|
||||
id = 'device_layout',
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
id = "device_margin",
|
||||
id = 'device_margin',
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.network_manager.access_point.bg,
|
||||
fg = Theme_config.network_manager.access_point.fg,
|
||||
border_color = Theme_config.network_manager.access_point.border_color,
|
||||
border_width = Theme_config.network_manager.access_point.border_width,
|
||||
id = "background",
|
||||
id = 'background',
|
||||
shape = Theme_config.network_manager.access_point.device_shape,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
})
|
||||
|
||||
assert(type(ret) == 'table', 'access_point:ret is not a table')
|
||||
|
||||
gtable.crush(ret, access_point, true)
|
||||
|
||||
ret.NetworkManagerAccessPoint = args.NetworkManagerAccessPoint
|
||||
@@ -256,49 +258,49 @@ function access_point.new(args)
|
||||
|
||||
ret.NetworkManagerAccessPointProperties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.DBus.Properties',
|
||||
path = ret.NetworkManagerAccessPoint.object_path,
|
||||
}
|
||||
|
||||
-- Update the access point strength
|
||||
ret.NetworkManagerAccessPointProperties:connect_signal(function(_, properties, data)
|
||||
if data.Strength then
|
||||
awesome.emit_signal("NM::AccessPointStrength", data.Strength)
|
||||
awesome.emit_signal('NM::AccessPointStrength', data.Strength)
|
||||
if ret.is_ap_active(ret.NetworkManagerAccessPoint.object_path) then
|
||||
ret:get_children_by_id("icon")[1].image = gcolor.recolor_image(
|
||||
icondir .. "wifi-strength-" .. math.floor(data.Strength / 25) + 1 .. ".svg",
|
||||
ret:get_children_by_id('icon')[1].image = gcolor.recolor_image(
|
||||
icondir .. 'wifi-strength-' .. math.floor(data.Strength / 25) + 1 .. '.svg',
|
||||
Theme_config.network_manager.access_point.icon_color2)
|
||||
else
|
||||
ret:get_children_by_id("icon")[1].image = gcolor.recolor_image(
|
||||
icondir .. "wifi-strength-" .. math.floor(data.Strength / 25) + 1 .. ".svg",
|
||||
ret:get_children_by_id('icon')[1].image = gcolor.recolor_image(
|
||||
icondir .. 'wifi-strength-' .. math.floor(data.Strength / 25) + 1 .. '.svg',
|
||||
Theme_config.network_manager.access_point.icon_color)
|
||||
end
|
||||
end
|
||||
end, "PropertiesChanged")
|
||||
end, 'PropertiesChanged')
|
||||
|
||||
if ret:is_ap_active(ret.NetworkManagerAccessPoint) then
|
||||
ret.bg = Theme_config.network_manager.access_point.fg
|
||||
ret.fg = Theme_config.network_manager.access_point.bg
|
||||
ret:get_children_by_id("icon")[1].image = gcolor.recolor_image(
|
||||
icondir .. "wifi-strength-" .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. ".svg",
|
||||
ret:get_children_by_id('icon')[1].image = gcolor.recolor_image(
|
||||
icondir .. 'wifi-strength-' .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. '.svg',
|
||||
Theme_config.network_manager.access_point.icon_color2)
|
||||
ret:get_children_by_id("con")[1].image = gcolor.recolor_image(
|
||||
icondir .. "link.svg", Theme_config.network_manager.access_point.icon_color2)
|
||||
ret:get_children_by_id('con')[1].image = gcolor.recolor_image(
|
||||
icondir .. 'link.svg', Theme_config.network_manager.access_point.icon_color2)
|
||||
else
|
||||
ret.bg = Theme_config.network_manager.access_point.bg
|
||||
ret.fg = Theme_config.network_manager.access_point.fg
|
||||
ret:get_children_by_id("icon")[1].image = gcolor.recolor_image(
|
||||
icondir .. "wifi-strength-" .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. ".svg",
|
||||
ret:get_children_by_id('icon')[1].image = gcolor.recolor_image(
|
||||
icondir .. 'wifi-strength-' .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. '.svg',
|
||||
Theme_config.network_manager.access_point.icon_color)
|
||||
ret:get_children_by_id("con")[1].image = gcolor.recolor_image(
|
||||
icondir .. "link.svg", Theme_config.network_manager.access_point.icon_color)
|
||||
ret:get_children_by_id('con')[1].image = gcolor.recolor_image(
|
||||
icondir .. 'link.svg', Theme_config.network_manager.access_point.icon_color)
|
||||
end
|
||||
|
||||
ret.ap_form = ap_form {
|
||||
screen = args.screen,
|
||||
NetworkManagerAccessPoint = args.NetworkManagerAccessPoint,
|
||||
ap = ret
|
||||
ap = ret,
|
||||
}
|
||||
|
||||
ret.cm = cm {
|
||||
@@ -309,40 +311,40 @@ function access_point.new(args)
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'text_role',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
}, spacing = dpi(10),
|
||||
entries = {
|
||||
{ -- Connect/Disconnect a device
|
||||
name = "ret.device.Connected" and "Disconnect" or "Connect",
|
||||
icon = gcolor.recolor_image("ret.device.Connected" and icondir .. "link-off.svg" or
|
||||
icondir .. "link.svg",
|
||||
name = 'ret.device.Connected' and 'Disconnect' or 'Connect',
|
||||
icon = gcolor.recolor_image('ret.device.Connected' and icondir .. 'link-off.svg' or
|
||||
icondir .. 'link.svg',
|
||||
Theme_config.network_manager.access_point.icon_color),
|
||||
callback = function()
|
||||
ret:toggle_connection(ret.NetworkManagerAccessPoint)
|
||||
end,
|
||||
id = "connected"
|
||||
}
|
||||
}
|
||||
id = 'connected',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ret:buttons(gtable.join(
|
||||
@@ -362,7 +364,7 @@ function access_point.new(args)
|
||||
)
|
||||
))
|
||||
|
||||
Hover_signal(ret)
|
||||
hover.bg_hover { widget = ret }
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
local abutton = require("awful.button")
|
||||
local aplacement = require("awful.placement")
|
||||
local apopup = require("awful.popup")
|
||||
local awidget = require("awful.widget")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears.table")
|
||||
local gcolor = require("gears.color")
|
||||
local gshape = require("gears.shape")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local NM = require("lgi").NM
|
||||
local wibox = require("wibox")
|
||||
local abutton = require('awful.button')
|
||||
local aplacement = require('awful.placement')
|
||||
local apopup = require('awful.popup')
|
||||
local awidget = require('awful.widget')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gtable = require('gears.table')
|
||||
local gcolor = require('gears.color')
|
||||
local gshape = require('gears.shape')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local NM = require('lgi').NM
|
||||
local wibox = require('wibox')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/network/"
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/'
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
mousegrabber = mousegrabber
|
||||
mousegrabber = mousegrabber,
|
||||
}
|
||||
|
||||
local ap_form = { mt = {} }
|
||||
@@ -28,7 +30,7 @@ function ap_form.new(args)
|
||||
args = args or {}
|
||||
args.screen = args.screen
|
||||
|
||||
local password = awidget.inputbox { hint_text = "Password..." }
|
||||
local password = awidget.inputbox { hint_text = 'Password...' }
|
||||
|
||||
local ret = apopup {
|
||||
widget = {
|
||||
@@ -40,31 +42,31 @@ function ap_form.new(args)
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = NM.utils_ssid_to_utf8(args.NetworkManagerAccessPoint.Ssid),
|
||||
font = User_config.font.specify .. ",extra bold 16",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
font = User_config.font.specify .. ',extra bold 16',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(5)
|
||||
margins = dpi(5),
|
||||
},
|
||||
{ -- Close button
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = gcolor.recolor_image(icondir .. "close.svg", Theme_config.network_manager.form.icon_fg),
|
||||
image = gcolor.recolor_image(icondir .. 'close.svg', Theme_config.network_manager.form.icon_fg),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(5),
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
shape = Theme_config.network_manager.form.close_icon_shape,
|
||||
id = "close_button",
|
||||
bg = Theme_config.network_manager.form.close_bg
|
||||
id = 'close_button',
|
||||
bg = Theme_config.network_manager.form.close_bg,
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.network_manager.form.header_bg,
|
||||
@@ -73,9 +75,9 @@ function ap_form.new(args)
|
||||
{ -- Form
|
||||
{ -- Password
|
||||
widget = wibox.widget.textbox,
|
||||
text = "Password",
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
text = 'Password',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
{
|
||||
widget = wibox.container.margin,
|
||||
@@ -89,25 +91,25 @@ function ap_form.new(args)
|
||||
password,
|
||||
widget = wibox.container.margin,
|
||||
margins = 5,
|
||||
id = "marg"
|
||||
id = 'marg',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = 400,
|
||||
height = 50,
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
bg = "#212121",
|
||||
fg = "#F0F0F0",
|
||||
border_color = "#414141",
|
||||
bg = '#212121',
|
||||
fg = '#F0F0F0',
|
||||
border_color = '#414141',
|
||||
border_width = 2,
|
||||
shape = gshape.rounded_rect,
|
||||
forced_width = 300,
|
||||
forced_height = 50,
|
||||
id = "password_container"
|
||||
id = 'password_container',
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
{ -- Actions
|
||||
{ -- Auto connect
|
||||
@@ -121,26 +123,26 @@ function ap_form.new(args)
|
||||
check_color = Theme_config.network_manager.form.checkbox_bg,
|
||||
border_color = Theme_config.network_manager.form.checkbox_bg,
|
||||
border_width = 2,
|
||||
id = "checkbox",
|
||||
widget = wibox.widget.checkbox
|
||||
id = 'checkbox',
|
||||
widget = wibox.widget.checkbox,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = dpi(30),
|
||||
height = dpi(30)
|
||||
height = dpi(30),
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = "Auto connect",
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
text = 'Auto connect',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
nil,
|
||||
{ -- Connect
|
||||
@@ -148,9 +150,9 @@ function ap_form.new(args)
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = "Connect",
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
text = 'Connect',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(10),
|
||||
@@ -159,18 +161,18 @@ function ap_form.new(args)
|
||||
bg = Theme_config.network_manager.form.button_bg,
|
||||
fg = Theme_config.network_manager.form.button_fg,
|
||||
shape = Theme_config.network_manager.form.button_shape,
|
||||
id = "connect_button",
|
||||
id = 'connect_button',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(10),
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
spacing = dpi(20),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(10)
|
||||
margins = dpi(10),
|
||||
},
|
||||
placement = aplacement.centered,
|
||||
ontop = true,
|
||||
@@ -182,55 +184,55 @@ function ap_form.new(args)
|
||||
shape = Theme_config.network_manager.form.shape,
|
||||
border_color = Theme_config.network_manager.form.border_color,
|
||||
border_width = Theme_config.network_manager.form.border_width,
|
||||
type = "dialog",
|
||||
type = 'dialog',
|
||||
screen = args.screen,
|
||||
}
|
||||
|
||||
local password_container = ret.widget:get_children_by_id("password_container")[1]
|
||||
local password_container = ret.widget:get_children_by_id('password_container')[1]
|
||||
|
||||
gtable.crush(ret, ap_form, true)
|
||||
|
||||
-- Focus the searchbar when its left clicked
|
||||
password_container:buttons(gtable.join {
|
||||
abutton({}, 1, function()
|
||||
password:focus()
|
||||
end)
|
||||
end),
|
||||
})
|
||||
|
||||
--#region Hover signals to change the cursor to a text cursor
|
||||
local old_cursor, old_wibox
|
||||
password_container:connect_signal("mouse::enter", function()
|
||||
password_container:connect_signal('mouse::enter', function()
|
||||
local wid = capi.mouse.current_wibox
|
||||
if wid then
|
||||
old_cursor, old_wibox = wid.cursor, wid
|
||||
wid.cursor = "xterm"
|
||||
wid.cursor = 'xterm'
|
||||
end
|
||||
end)
|
||||
password_container:connect_signal("mouse::leave", function()
|
||||
password_container:connect_signal('mouse::leave', function()
|
||||
old_wibox.cursor = old_cursor
|
||||
old_wibox = nil
|
||||
end)
|
||||
--#endregion
|
||||
|
||||
gtable.crush(ret, ap_form, true)
|
||||
|
||||
local checkbox = ret.widget:get_children_by_id("checkbox")[1]
|
||||
checkbox:connect_signal("button::press", function()
|
||||
local checkbox = ret.widget:get_children_by_id('checkbox')[1]
|
||||
checkbox:connect_signal('button::press', function()
|
||||
checkbox.checked = not checkbox.checked
|
||||
end)
|
||||
|
||||
local close_button = ret.widget:get_children_by_id("close_button")[1]
|
||||
close_button:connect_signal("button::press", function()
|
||||
local close_button = ret.widget:get_children_by_id('close_button')[1]
|
||||
close_button:connect_signal('button::press', function()
|
||||
ret:popup_toggle()
|
||||
end)
|
||||
Hover_signal(close_button)
|
||||
hover.bg_hover { widget = close_button }
|
||||
|
||||
local connect_button = ret.widget:get_children_by_id("connect_button")[1]
|
||||
connect_button:connect_signal("button::press", function()
|
||||
local connect_button = ret.widget:get_children_by_id('connect_button')[1]
|
||||
connect_button:connect_signal('button::press', function()
|
||||
password:stop()
|
||||
args.ap:connect(args.NetworkManagerAccessPoint, password:get_text(),
|
||||
ret.widget:get_children_by_id("checkbox")[1].checked)
|
||||
ret.widget:get_children_by_id('checkbox')[1].checked)
|
||||
ret:popup_toggle()
|
||||
end)
|
||||
Hover_signal(connect_button)
|
||||
hover.bg_hover { widget = connect_button }
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -3,28 +3,29 @@
|
||||
------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require("awful.button")
|
||||
local base = require("wibox.widget.base")
|
||||
local dbus_proxy = require("src.lib.lua-dbus_proxy.src.dbus_proxy")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gcolor = require("gears.color")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local gshape = require("gears.shape")
|
||||
local gtable = require("gears.table")
|
||||
local gtimer = require("gears.timer")
|
||||
local lgi = require("lgi")
|
||||
local abutton = require('awful.button')
|
||||
local base = require('wibox.widget.base')
|
||||
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gshape = require('gears.shape')
|
||||
local gtable = require('gears.table')
|
||||
local gtimer = require('gears.timer')
|
||||
local lgi = require('lgi')
|
||||
local NM = lgi.NM
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local naughty = require('naughty')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Third party libs
|
||||
local rubato = require("src.lib.rubato")
|
||||
local rubato = require('src.lib.rubato')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
-- Local libs
|
||||
local access_point = require("src.modules.network_controller.access_point")
|
||||
local dnd_widget = require("awful.widget.toggle_widget")
|
||||
local access_point = require('src.modules.network_controller.access_point')
|
||||
local dnd_widget = require('awful.widget.toggle_widget')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/network/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/'
|
||||
|
||||
local network = { mt = {} }
|
||||
|
||||
@@ -41,7 +42,7 @@ network.NMState = {
|
||||
|
||||
network.DeviceType = {
|
||||
ETHERNET = 1,
|
||||
WIFI = 2
|
||||
WIFI = 2,
|
||||
}
|
||||
|
||||
network.DeviceState = {
|
||||
@@ -57,7 +58,7 @@ network.DeviceState = {
|
||||
SECONDARIES = 90,
|
||||
ACTIVATED = 100,
|
||||
DEACTIVATING = 110,
|
||||
FAILED = 120
|
||||
FAILED = 120,
|
||||
}
|
||||
|
||||
---Get the wifi and or ethernet proxy and connect to their PropertiesChanged signal
|
||||
@@ -73,9 +74,9 @@ function network:get_active_device()
|
||||
--Create a new proxy for every device
|
||||
local NetworkManagerDevice = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.Device",
|
||||
path = path
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.Device',
|
||||
path = path,
|
||||
}
|
||||
|
||||
--Check if the device is either a wifi or ethernet device, and if its activated
|
||||
@@ -87,92 +88,87 @@ function network:get_active_device()
|
||||
--New wifi proxy to check the bitrate
|
||||
self._private.NetworkManagerDeviceWireless = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.Device.Wireless",
|
||||
path = path
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.Device.Wireless',
|
||||
path = path,
|
||||
}
|
||||
-- Watch PropertiesChanged and update the bitrate
|
||||
local NetworkManagerDeviceWirelessProperties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
path = self._private.NetworkManagerDeviceWireless.object_path
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.DBus.Properties',
|
||||
path = self._private.NetworkManagerDeviceWireless.object_path,
|
||||
}
|
||||
|
||||
NetworkManagerDeviceWirelessProperties:connect_signal(function(_, properties, data)
|
||||
if data.Bitrate then
|
||||
self:emit_signal("NM::Bitrate", data.Bitrate)
|
||||
self:emit_signal('NM::Bitrate', data.Bitrate)
|
||||
end
|
||||
end, "PropertiesChanged")
|
||||
end, 'PropertiesChanged')
|
||||
-- Watch the StateChanged signal, update and notify when a new AP is connected
|
||||
self._private.NetworkManagerDevice:connect_signal(function(proxy, new_state)
|
||||
local NetworkManagerAccessPoint = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.AccessPoint",
|
||||
path = self._private.NetworkManagerDeviceWireless.ActiveAccessPoint
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.AccessPoint',
|
||||
path = self._private.NetworkManagerDeviceWireless.ActiveAccessPoint,
|
||||
}
|
||||
|
||||
if new_state == network.DeviceState.ACTIVATED then
|
||||
local ssid = NM.utils_ssid_to_utf8(NetworkManagerAccessPoint.Ssid)
|
||||
self:emit_signal("NM::AccessPointConnected", ssid, NetworkManagerAccessPoint.Strength)
|
||||
self:emit_signal('NM::AccessPointConnected', ssid, NetworkManagerAccessPoint.Strength)
|
||||
end
|
||||
end, "StateChanged")
|
||||
end, 'StateChanged')
|
||||
|
||||
elseif (NetworkManagerDevice.DeviceType == network.DeviceType.ETHERNET) and
|
||||
(NetworkManagerDevice.State == network.DeviceState.ACTIVATED) then
|
||||
-- Create a new ethernet device and set it as the active device
|
||||
self._private.NetworkManagerDevice = NetworkManagerDevice
|
||||
self._private.NetworkManagerDeviceWired = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.Device.Wired",
|
||||
path = path
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.Device.Wired',
|
||||
path = path,
|
||||
}
|
||||
|
||||
local NetworkManagerDeviceWiredProperties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
path = self._private.NetworkManagerDeviceWired.object_path
|
||||
}
|
||||
|
||||
-- Watch the PropertiesChanged signal and update the speed and carrier
|
||||
NetworkManagerDeviceWiredProperties:connect_signal(function(_, properties, data)
|
||||
if data.Speed then
|
||||
print(data.Speed)
|
||||
self:emit_signal("NM::Speed", data.Speed)
|
||||
elseif data.Carrier then
|
||||
print(data.Carrier)
|
||||
self:emit_signal("NM::Carrier", data.Carrier)
|
||||
end
|
||||
end, "PropertiesChanged")
|
||||
|
||||
if self._private.NetworkManagerDevice.State == network.DeviceState.ACTIVATED then
|
||||
awesome.emit_signal('NM::EthernetStatus', true, self._private.NetworkManagerDeviceWired.Speed)
|
||||
end
|
||||
-- Connect to the StateChanged signal and notify when the wired connection is ready
|
||||
self._private.NetworkManagerDevice:connect_signal(function(proxy, new_state)
|
||||
self._private.NetworkManagerDevice:connect_signal(function(_, new_state)
|
||||
if new_state == network.DeviceState.ACTIVATED then
|
||||
self:emit_signal("NM::EthernetActive")
|
||||
print("Ethernet active")
|
||||
awesome.emit_signal('NM::EthernetStatus', true, self._private.NetworkManagerDeviceWired.Speed)
|
||||
elseif new_state == network.DeviceState.DISCONNECTED then
|
||||
awesome.emit_signal('NM::EthernetStatus', false)
|
||||
end
|
||||
end, "StateChanged")
|
||||
end, 'StateChanged')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function network:get_active_ap_ssid()
|
||||
local d = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.Device.Wireless',
|
||||
path = self._private.NetworkManagerDeviceWireless.ActiveAccessPoint,
|
||||
}
|
||||
|
||||
return NM.utils_ssid_to_utf8(d.Ssid)
|
||||
end
|
||||
|
||||
---Scan for access points and create a widget for each one.
|
||||
function network:scan_access_points()
|
||||
if not self._private.NetworkManagerDeviceWireless then return end
|
||||
local ap_list = self:get_children_by_id("wifi_ap_list")[1]
|
||||
local ap_list = self:get_children_by_id('wifi_ap_list')[1]
|
||||
ap_list:reset()
|
||||
local ap_table = {}
|
||||
self._private.NetworkManagerDeviceWireless:RequestScanAsync(function(_, _, _, failure)
|
||||
if failure then
|
||||
naughty.notification {
|
||||
app_icon = icondir .. "ethernet.svg",
|
||||
app_name = "Network Manager",
|
||||
title = "Error: Scan failed!",
|
||||
message = "Failed to scan for access points.\n" .. failure,
|
||||
icon = gcolor.recolor_image(icondir .. "ethernet.svg", Theme_config.network.icon_color),
|
||||
app_icon = icondir .. 'ethernet.svg',
|
||||
app_name = 'Network Manager',
|
||||
title = 'Error: Scan failed!',
|
||||
message = 'Failed to scan for access points.\n' .. failure,
|
||||
icon = gcolor.recolor_image(icondir .. 'ethernet.svg', Theme_config.network.icon_color),
|
||||
timeout = 5,
|
||||
}
|
||||
return
|
||||
@@ -183,9 +179,9 @@ function network:scan_access_points()
|
||||
-- Create a new proxy for every ap
|
||||
local NetworkManagerAccessPoint = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.AccessPoint",
|
||||
path = ap
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.AccessPoint',
|
||||
path = ap,
|
||||
}
|
||||
|
||||
-- We are only interested in those with a ssid
|
||||
@@ -216,17 +212,17 @@ function network:scan_access_points()
|
||||
NetworkManagerDevice = self._private.NetworkManagerDevice,
|
||||
NetworkManagerSettings = self._private.NetworkManagerSettings,
|
||||
NetworkManager = self._private.NetworkManager,
|
||||
NetworkManagerDeviceWireless = self._private.NetworkManagerDeviceWireless
|
||||
NetworkManagerDeviceWireless = self._private.NetworkManagerDeviceWireless,
|
||||
})
|
||||
end
|
||||
end, { call_id = "my-id" }, {})
|
||||
end, { call_id = 'my-id' }, {})
|
||||
end
|
||||
|
||||
---Toggles networking on or off
|
||||
function network:toggle_wifi()
|
||||
local enable = not self._private.NetworkManager.WirelessEnabled
|
||||
self._private.NetworkManager:Set("org.freedesktop.NetworkManager", "WirelessEnabled", lgi.GLib.Variant("b", enable))
|
||||
self._private.NetworkManager.WirelessEnabled = { signature = "b", value = enable }
|
||||
self._private.NetworkManager:Set('org.freedesktop.NetworkManager', 'WirelessEnabled', lgi.GLib.Variant('b', enable))
|
||||
self._private.NetworkManager.WirelessEnabled = { signature = 'b', value = enable }
|
||||
end
|
||||
|
||||
function network.new(args)
|
||||
@@ -242,54 +238,54 @@ function network.new(args)
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. "menu-down.svg",
|
||||
image = gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.network_manager.wifi_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon"
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon',
|
||||
},
|
||||
id = "center",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
id = 'center',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{
|
||||
{
|
||||
text = "Wifi Networks",
|
||||
text = 'Wifi Networks',
|
||||
widget = wibox.widget.textbox,
|
||||
id = "ap_name"
|
||||
id = 'ap_name',
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "wifi",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
id = 'wifi',
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = "wifi_bg",
|
||||
id = 'wifi_bg',
|
||||
bg = Theme_config.network_manager.wifi_bg,
|
||||
fg = Theme_config.network_manager.wifi_fg,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(4))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
id = "wifi_margin",
|
||||
widget = wibox.container.margin
|
||||
id = 'wifi_margin',
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
id = "wifi_list",
|
||||
id = 'wifi_list',
|
||||
{
|
||||
{
|
||||
step = dpi(50),
|
||||
spacing = dpi(10),
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
id = "wifi_ap_list"
|
||||
id = 'wifi_ap_list',
|
||||
},
|
||||
id = "margin",
|
||||
id = 'margin',
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
border_color = Theme_config.network_manager.ap_border_color,
|
||||
border_width = Theme_config.network_manager.ap_border_width,
|
||||
@@ -297,35 +293,35 @@ function network.new(args)
|
||||
gshape.partially_rounded_rect(cr, width, height, false, false, true, true, dpi(4))
|
||||
end,
|
||||
widget = wibox.container.background,
|
||||
forced_height = 0
|
||||
forced_height = 0,
|
||||
},
|
||||
{
|
||||
{ -- action buttons
|
||||
{
|
||||
dnd_widget {
|
||||
color = Theme_config.network_manager.power_icon_color,
|
||||
size = dpi(40)
|
||||
size = dpi(40),
|
||||
},
|
||||
id = "dnd",
|
||||
id = 'dnd',
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center"
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
nil,
|
||||
{ -- refresh
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. "refresh.svg",
|
||||
image = gcolor.recolor_image(icondir .. 'refresh.svg',
|
||||
Theme_config.network_manager.refresh_icon_color),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
id = "icon"
|
||||
id = 'icon',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(5),
|
||||
id = "center",
|
||||
id = 'center',
|
||||
},
|
||||
border_width = dpi(2),
|
||||
border_color = Theme_config.network_manager.border_color,
|
||||
@@ -334,20 +330,20 @@ function network.new(args)
|
||||
end,
|
||||
bg = Theme_config.network_manager.refresh_bg,
|
||||
widget = wibox.container.background,
|
||||
id = "refresh"
|
||||
id = 'refresh',
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(10),
|
||||
id = "action_buttons"
|
||||
id = 'action_buttons',
|
||||
},
|
||||
id = "layout1",
|
||||
layout = wibox.layout.fixed.vertical
|
||||
id = 'layout1',
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
id = "margin",
|
||||
id = 'margin',
|
||||
margins = dpi(15),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(8))
|
||||
@@ -355,17 +351,19 @@ function network.new(args)
|
||||
border_color = Theme_config.network_manager.border_color,
|
||||
border_width = Theme_config.network_manager.border_width,
|
||||
bg = Theme_config.network_manager.bg,
|
||||
id = "background",
|
||||
widget = wibox.container.background
|
||||
id = 'background',
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
width = dpi(400),
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
})
|
||||
|
||||
local dnd = ret:get_children_by_id("dnd")[1]:get_widget()
|
||||
assert(type(ret) == 'table', 'NetworkManager is not running')
|
||||
|
||||
dnd:connect_signal("dnd::toggle", function(enable)
|
||||
local dnd = ret:get_children_by_id('dnd')[1]:get_widget()
|
||||
|
||||
dnd:connect_signal('dnd::toggle', function(enable)
|
||||
ret:toggle_wifi()
|
||||
end)
|
||||
|
||||
@@ -375,23 +373,23 @@ function network.new(args)
|
||||
|
||||
ret._private.NetworkManager = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager",
|
||||
path = "/org/freedesktop/NetworkManager",
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager',
|
||||
path = '/org/freedesktop/NetworkManager',
|
||||
}
|
||||
|
||||
ret._private.NetworkManagerSettings = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.Settings",
|
||||
path = "/org/freedesktop/NetworkManager/Settings",
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.Settings',
|
||||
path = '/org/freedesktop/NetworkManager/Settings',
|
||||
}
|
||||
|
||||
ret._private.NetworkManagerProperties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
path = "/org/freedesktop/NetworkManager",
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.DBus.Properties',
|
||||
path = '/org/freedesktop/NetworkManager',
|
||||
}
|
||||
|
||||
ret._private.NetworkManagerProperties:connect_signal(function(_, properties, data)
|
||||
@@ -404,7 +402,7 @@ function network.new(args)
|
||||
dnd:set_disabled()
|
||||
end
|
||||
|
||||
ret:emit_signal("NetworkManager::status", ret._private.WirelessEnabled)
|
||||
ret:emit_signal('NetworkManager::status', ret._private.WirelessEnabled)
|
||||
|
||||
if data.WirelessEnabled then
|
||||
gtimer {
|
||||
@@ -414,11 +412,11 @@ function network.new(args)
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
ret:scan_access_points()
|
||||
end
|
||||
end,
|
||||
}
|
||||
end
|
||||
end
|
||||
end, "PropertiesChanged")
|
||||
end, 'PropertiesChanged')
|
||||
|
||||
ret:get_active_device()
|
||||
|
||||
@@ -433,9 +431,9 @@ function network.new(args)
|
||||
--#endregion
|
||||
|
||||
--#region Dropdown logic
|
||||
local wifi_margin = ret:get_children_by_id("wifi_margin")[1]
|
||||
local wifi_list = ret:get_children_by_id("wifi_list")[1]
|
||||
local wifi = ret:get_children_by_id("wifi")[1].center
|
||||
local wifi_margin = ret:get_children_by_id('wifi_margin')[1]
|
||||
local wifi_list = ret:get_children_by_id('wifi_list')[1]
|
||||
local wifi = ret:get_children_by_id('wifi')[1].center
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.2,
|
||||
@@ -443,14 +441,14 @@ function network.new(args)
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
wifi_list.forced_height = v
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
wifi_margin:buttons(gtable.join(
|
||||
abutton({}, 1, nil,
|
||||
function()
|
||||
if wifi_list.forced_height == 0 then
|
||||
if not ret:get_children_by_id("wifi_ap_list")[1].children then
|
||||
if not ret:get_children_by_id('wifi_ap_list')[1].children then
|
||||
return
|
||||
end
|
||||
local size = (5 * 49) + 1
|
||||
@@ -461,30 +459,29 @@ function network.new(args)
|
||||
wifi_margin.wifi_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
wifi.icon:set_image(gcolor.recolor_image(icondir .. "menu-up.svg",
|
||||
wifi.icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.network_manager.wifi_icon_color))
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
wifi_margin.wifi_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, true, true, dpi(4))
|
||||
end
|
||||
wifi.icon:set_image(gcolor.recolor_image(icondir .. "menu-down.svg",
|
||||
wifi.icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.network_manager.wifi_icon_color))
|
||||
end
|
||||
end
|
||||
)
|
||||
))
|
||||
hover.bg_hover { widget = wifi_margin.wifi_bg }
|
||||
--#endregion
|
||||
|
||||
local refresh_button = ret:get_children_by_id("refresh")[1]
|
||||
local refresh_button = ret:get_children_by_id('refresh')[1]
|
||||
refresh_button:buttons(gtable.join(
|
||||
abutton({}, 1, nil,
|
||||
function()
|
||||
ret:scan_access_points()
|
||||
end
|
||||
)
|
||||
abutton({}, 1, nil, function()
|
||||
ret:scan_access_points()
|
||||
end)
|
||||
))
|
||||
Hover_signal(refresh_button)
|
||||
hover.bg_hover { widget = refresh_button }
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -3,286 +3,303 @@
|
||||
-------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local dnd_widget = require("awful.widget.toggle_widget")
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local base = require('wibox.widget.base')
|
||||
local wibox = require('wibox')
|
||||
local apopup = require('awful.popup')
|
||||
local aplacement = require('awful.placement')
|
||||
local gshape = require('gears.shape')
|
||||
local gcolor = require('gears.color')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
-- Own Libs
|
||||
local dnd_widget = require('awful.widget.toggle_widget')
|
||||
local notification_list = require('src.modules.notification-center.widgets.notification_list')()
|
||||
local weather_widget = require('src.modules.notification-center.widgets.weather')()
|
||||
local profile_widget = require('src.modules.notification-center.widgets.profile')()
|
||||
local status_bars = require('src.modules.notification-center.widgets.status_bars')()
|
||||
local music_widget = require('src.modules.notification-center.widgets.song_info')()
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/notifications/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/'
|
||||
|
||||
return function(s)
|
||||
local capi = {
|
||||
client = client,
|
||||
}
|
||||
|
||||
local dnd = dnd_widget({
|
||||
text = "Do not disturb",
|
||||
color = Theme_config.notification_center.dnd_color,
|
||||
fg = Theme_config.notification_center.dnd_fg,
|
||||
size = dpi(40)
|
||||
})
|
||||
local instance = nil
|
||||
|
||||
dnd:get_widget():connect_signal("dnd::toggle", function(enabled)
|
||||
User_config.dnd = enabled
|
||||
end)
|
||||
local info_center = {}
|
||||
|
||||
--#region Activation area
|
||||
function info_center:toggle()
|
||||
if self.container.visible then
|
||||
self.container.visible = false
|
||||
else
|
||||
self.container.visible = true
|
||||
end
|
||||
end
|
||||
|
||||
local activation_area = awful.popup {
|
||||
bg = '#00000000',
|
||||
widget = wibox.container.background,
|
||||
ontop = true,
|
||||
screen = s,
|
||||
type = 'dock',
|
||||
placement = function(c)
|
||||
awful.placement.top(c)
|
||||
end,
|
||||
}
|
||||
function info_center.new(args)
|
||||
args = args or {}
|
||||
|
||||
activation_area:setup({
|
||||
widget = wibox.container.background,
|
||||
forced_height = dpi(1),
|
||||
forced_width = dpi(300),
|
||||
bg = '#00000000',
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
})
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"notification_center_activation::toggle",
|
||||
function(screen, hide)
|
||||
if screen == s then
|
||||
activation_area.visible = hide
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
--#endregion
|
||||
|
||||
--#region Widgets
|
||||
local nl = require("src.modules.notification-center.notification_list").notification_list
|
||||
local music_widget = require("src.modules.notification-center.song_info")()
|
||||
local time_date = require("src.modules.notification-center.time_date")()
|
||||
local weather_widget = require("src.modules.notification-center.weather")()
|
||||
local profile_widget = require("src.modules.notification-center.profile")()
|
||||
local status_bars_widget = require("src.modules.notification-center.status_bars")()
|
||||
--#endregion
|
||||
|
||||
--#region Notification buttons
|
||||
local clear_all_widget = wibox.widget { -- Clear all button
|
||||
local w = base.make_widget_from_value {
|
||||
{
|
||||
{
|
||||
{
|
||||
text = "Clear",
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "clearall"
|
||||
{
|
||||
{
|
||||
{ -- Time
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
format = "<span foreground='#18FFFF' font='JetBrainsMono Nerd Font, Bold 46'><b>%H:%M</b></span>",
|
||||
widget = wibox.widget.textclock,
|
||||
},
|
||||
{ -- Date and Day
|
||||
{ -- Date
|
||||
halign = 'left',
|
||||
valign = 'bottom',
|
||||
format = "<span foreground='#69F0AE' font='JetBrainsMono Nerd Font, Regular 18'><b>%d</b></span><span foreground='#18FFFF' font='JetBrainsMono Nerd Font, Regular 18'><b> %b %Y</b></span>",
|
||||
widget = wibox.widget.textclock,
|
||||
},
|
||||
{ -- Day
|
||||
halign = 'left',
|
||||
valign = 'top',
|
||||
format = "<span foreground='#69F0AE' font='JetBrainsMono Nerd Font, Bold 20'><b>%A</b></span>",
|
||||
widget = wibox.widget.textclock,
|
||||
},
|
||||
layout = wibox.layout.flex.vertical,
|
||||
},
|
||||
spacing = dpi(20),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
bg = Theme_config.notification_center.spacing_line.color,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(2),
|
||||
strategy = 'exact',
|
||||
},
|
||||
left = dpi(60),
|
||||
right = dpi(60),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "background4",
|
||||
fg = Theme_config.notification_center.clear_all_button.fg,
|
||||
bg = Theme_config.notification_center.clear_all_button.bg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, 12)
|
||||
end,
|
||||
forced_width = dpi(80),
|
||||
forced_height = dpi(40),
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "margin3",
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
valign = "bottom",
|
||||
halign = "right",
|
||||
}
|
||||
|
||||
local no_notification_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
resize = true,
|
||||
forced_height = dpi(200),
|
||||
forced_width = dpi(200),
|
||||
image = icondir .. "megamind.svg",
|
||||
widget = wibox.widget.imagebox,
|
||||
id = "icon"
|
||||
},
|
||||
{
|
||||
id = "txt",
|
||||
markup = "<span color='#414141' font='JetBrainsMono Nerd Font, ExtraBold 20'>No Notifications?</span>",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "lay",
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place
|
||||
}
|
||||
--#endregion
|
||||
|
||||
--#region Notification center
|
||||
local notification_center = awful.popup {
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.notification_center.bg,
|
||||
border_color = Theme_config.notification_center.border_color,
|
||||
border_width = Theme_config.notification_center.border_width,
|
||||
placement = function(c)
|
||||
awful.placement.top(c, { margins = dpi(10) })
|
||||
end,
|
||||
ontop = true,
|
||||
screen = s,
|
||||
visible = false,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(12))
|
||||
end,
|
||||
}
|
||||
|
||||
local function notification_center_setup()
|
||||
notification_center:setup({
|
||||
widget = notification_center,
|
||||
-- Custom widgets
|
||||
{
|
||||
time_date,
|
||||
require("src.modules.notification-center.spacingline_widget")(),
|
||||
{
|
||||
{
|
||||
weather_widget,
|
||||
{
|
||||
profile_widget,
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
status_bars_widget,
|
||||
status_bars,
|
||||
music_widget,
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
-- Notification list
|
||||
{
|
||||
{
|
||||
{
|
||||
nl,
|
||||
notification_list,
|
||||
height = dpi(680),
|
||||
strategy = "max",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
{
|
||||
no_notification_widget,
|
||||
strategy = "max",
|
||||
height = dpi(400),
|
||||
widget = wibox.container.constraint
|
||||
strategy = 'max',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
{
|
||||
dnd,
|
||||
{
|
||||
{
|
||||
{
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
resize = true,
|
||||
image = icondir .. 'megamind.svg',
|
||||
widget = wibox.widget.imagebox,
|
||||
id = 'no_notification_icon',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(200),
|
||||
width = dpi(200),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
markup = "<span color='#414141' font='JetBrainsMono Nerd Font, ExtraBold 20'>No Notifications?</span>",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'no_notification_text',
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
strategy = 'max',
|
||||
height = dpi(400),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
{
|
||||
dnd_widget {
|
||||
text = 'Do not disturb',
|
||||
color = Theme_config.notification_center.dnd_color,
|
||||
fg = Theme_config.notification_center.dnd_fg,
|
||||
size = dpi(40),
|
||||
},
|
||||
id = 'dnd',
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center"
|
||||
},
|
||||
nil,
|
||||
clear_all_widget,
|
||||
layout = wibox.layout.align.horizontal
|
||||
{ -- Clear all button
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
text = 'Clear',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'clear',
|
||||
},
|
||||
fg = Theme_config.notification_center.clear_all_button.fg,
|
||||
bg = Theme_config.notification_center.clear_all_button.bg,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 12)
|
||||
end,
|
||||
id = 'clear_all_bg',
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(80),
|
||||
height = dpi(40),
|
||||
strategy = 'exact',
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
valign = 'bottom', --? Needed?
|
||||
halign = 'right', --? Needed?
|
||||
},
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
id = "layout5",
|
||||
layout = wibox.layout.align.vertical
|
||||
layout = wibox.layout.align.vertical,
|
||||
},
|
||||
id = "margin6",
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "yes",
|
||||
spacing_widget = {
|
||||
{
|
||||
bg = Theme_config.notification_center.spacing_color,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
top = dpi(40),
|
||||
bottom = dpi(40),
|
||||
widget = wibox.container.margin
|
||||
thickness = dpi(2),
|
||||
color = Theme_config.notification_center.spacing_color,
|
||||
span_ratio = 0.9,
|
||||
widget = wibox.widget.separator,
|
||||
},
|
||||
spacing = dpi(1),
|
||||
forced_height = dpi(800),
|
||||
forced_width = dpi(1000),
|
||||
layout = wibox.layout.flex.horizontal
|
||||
})
|
||||
end
|
||||
spacing = dpi(2),
|
||||
layout = wibox.layout.flex.horizontal,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(800),
|
||||
width = dpi(1000),
|
||||
strategy = 'exact',
|
||||
}
|
||||
|
||||
--#endregion
|
||||
hover.bg_hover { widget = w:get_children_by_id('clear_all_bg')[1] }
|
||||
|
||||
--#region Signals
|
||||
-- Toggle notification_center visibility when mouse is over activation_area
|
||||
activation_area:connect_signal(
|
||||
"mouse::enter",
|
||||
function()
|
||||
notification_center.visible = true
|
||||
notification_center_setup()
|
||||
end
|
||||
)
|
||||
assert(type(w) == 'table', 'Widget creation failed')
|
||||
|
||||
-- Update the notification center popup and check if there are no notifications
|
||||
capi.awesome.connect_signal(
|
||||
"notification_center:update::needed",
|
||||
function()
|
||||
if #nl == 0 then
|
||||
math.randomseed(os.time())
|
||||
local prob = math.random(1, 10)
|
||||
notification_list:connect_signal('new_children', function()
|
||||
if #notification_list.children == 0 then
|
||||
math.randomseed(os.time())
|
||||
local prob = math.random(1, 10)
|
||||
|
||||
if (prob == 5) or (prob == 6) then
|
||||
no_notification_widget.lay.icon.image = icondir .. "megamind.svg"
|
||||
no_notification_widget.lay.txt.markup = "<span color='#414141' font='JetBrainsMono Nerd Font, ExtraBold 20'>No Notifications?</span>"
|
||||
else
|
||||
no_notification_widget.lay.icon.image = icondir .. "bell-outline.svg"
|
||||
no_notification_widget.lay.txt.markup = "<span color='#414141' font='JetBrainsMono Nerd Font, ExtraBold 20'>No Notification</span>"
|
||||
end
|
||||
no_notification_widget.visible = true
|
||||
if (prob == 5) or (prob == 6) then
|
||||
w:get_children_by_id('no_notification_icon')[1].image = icondir .. 'megamind.svg'
|
||||
w:get_children_by_id('no_notification_text')[1].markup = "<span color='#414141' font='JetBrainsMono Nerd Font, ExtraBold 20'>No Notifications?</span>"
|
||||
else
|
||||
no_notification_widget.visible = false
|
||||
w:get_children_by_id('no_notification_icon')[1].image = icondir .. 'bell-outline.svg'
|
||||
w:get_children_by_id('no_notification_text')[1].markup = "<span color='#414141' font='JetBrainsMono Nerd Font, ExtraBold 20'>No Notification</span>"
|
||||
end
|
||||
notification_center_setup()
|
||||
w:get_children_by_id('no_notification_icon')[1].visible = true
|
||||
w:get_children_by_id('no_notification_text')[1].visible = true
|
||||
else
|
||||
w:get_children_by_id('no_notification_icon')[1].visible = false
|
||||
w:get_children_by_id('no_notification_text')[1].visible = false
|
||||
end
|
||||
)
|
||||
|
||||
local function mouse_leave()
|
||||
notification_center.visible = false
|
||||
end
|
||||
|
||||
capi.awesome.connect_signal("notification_center::block_mouse_events", function()
|
||||
notification_center:disconnect_signal("mouse::leave", mouse_leave)
|
||||
end)
|
||||
|
||||
capi.awesome.connect_signal("notification_center::unblock_mouse_events", function()
|
||||
notification_center:connect_signal("mouse::leave", mouse_leave)
|
||||
w:get_children_by_id('clear')[1]:connect_signal('button::press', function()
|
||||
notification_list.children = {}
|
||||
notification_list:emit_signal('new_children')
|
||||
end)
|
||||
|
||||
-- Hide notification_center when mouse leaves it
|
||||
notification_center:connect_signal(
|
||||
"mouse::leave",
|
||||
mouse_leave
|
||||
)
|
||||
w:get_children_by_id('dnd')[1]:get_widget():connect_signal('dnd::toggle', function(enabled)
|
||||
User_config.dnd = enabled
|
||||
end)
|
||||
|
||||
-- Clear all notifications on button press
|
||||
clear_all_widget:connect_signal(
|
||||
"button::press",
|
||||
function()
|
||||
local size = #nl
|
||||
for i = 0, size do
|
||||
nl[i] = nil
|
||||
end
|
||||
capi.awesome.emit_signal("notification_center:update::needed")
|
||||
w.container = apopup {
|
||||
widget = w,
|
||||
bg = Theme_config.notification_center.bg,
|
||||
border_color = Theme_config.notification_center.border_color,
|
||||
border_width = Theme_config.notification_center.border_width,
|
||||
placement = function(c)
|
||||
aplacement.top(c, { margins = dpi(10) })
|
||||
end,
|
||||
ontop = true,
|
||||
screen = args.screen,
|
||||
visible = false,
|
||||
}
|
||||
|
||||
local activation_area = apopup {
|
||||
bg = gcolor.transparent,
|
||||
widget = {
|
||||
forced_height = dpi(1),
|
||||
forced_width = dpi(300),
|
||||
bg = gcolor.transparent,
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
ontop = true,
|
||||
screen = args.screen,
|
||||
type = 'dock',
|
||||
placement = function(c)
|
||||
aplacement.top(c)
|
||||
end,
|
||||
}
|
||||
|
||||
capi.client.connect_signal('property::fullscreen', function(c)
|
||||
if c.fullscreen then
|
||||
activation_area.visible = false
|
||||
else
|
||||
activation_area.visible = true
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
Hover_signal(clear_all_widget.margin3.background4)
|
||||
--#endregion
|
||||
activation_area:connect_signal('mouse::enter', function()
|
||||
w.container.visible = true
|
||||
end)
|
||||
|
||||
w.container:connect_signal('mouse::leave', function()
|
||||
w.container.visible = false
|
||||
end)
|
||||
|
||||
return w
|
||||
end
|
||||
|
||||
if not instance then
|
||||
instance = setmetatable(info_center, {
|
||||
__call = function(self, ...)
|
||||
self.new(...)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
return instance
|
||||
|
||||
@@ -1,268 +0,0 @@
|
||||
-------------------------------------
|
||||
-- This is the notification-center --
|
||||
-------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local naughty = require("naughty")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/notifications/"
|
||||
|
||||
local nl = {}
|
||||
|
||||
nl.notification_list = { layout = require("src.lib.overflow_widget.overflow").vertical, scrollbar_width = 0,
|
||||
step = dpi(100), spacing = dpi(20) }
|
||||
|
||||
-- @param {table} notification
|
||||
-- @return {widget} notifications_list
|
||||
function nl.create_notification(n)
|
||||
|
||||
n.time = os.time()
|
||||
|
||||
local time_ago_text = "- ago"
|
||||
|
||||
local timer_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
text = time_ago_text,
|
||||
widget = wibox.widget.textbox,
|
||||
id = "txt"
|
||||
},
|
||||
id = "background",
|
||||
fg = Theme_config.notification_center.notification_list.timer_fg,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
}
|
||||
|
||||
gears.timer {
|
||||
timeout = 1,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
local time_ago = math.floor(os.time() - n.time)
|
||||
local timer_text = timer_widget.background.txt
|
||||
if time_ago < 5 then
|
||||
timer_text:set_text("now")
|
||||
elseif time_ago < 60 then
|
||||
timer_text:set_text(time_ago .. "s ago")
|
||||
elseif time_ago < 3600 then
|
||||
timer_text:set_text(math.floor(time_ago / 60) .. "m ago")
|
||||
elseif time_ago < 86400 then
|
||||
timer_text:set_text(math.floor(time_ago / 3600) .. "h ago")
|
||||
else
|
||||
timer_text:set_text(math.floor(time_ago / 86400) .. "d ago")
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local close_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
font = User_config.font.specify .. ", 10",
|
||||
text = "✕",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
start_angle = 4.71239,
|
||||
thickness = dpi(2),
|
||||
min_value = 0,
|
||||
max_value = 360,
|
||||
value = 360,
|
||||
widget = wibox.container.arcchart,
|
||||
id = "arc_chart"
|
||||
},
|
||||
id = "background",
|
||||
fg = Theme_config.notification_center.notification_list.close_color,
|
||||
bg = Theme_config.notification_center.notification_list.close_bg,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
strategy = "exact",
|
||||
width = dpi(20),
|
||||
height = dpi(20),
|
||||
widget = wibox.container.constraint,
|
||||
id = "const"
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
}
|
||||
|
||||
local timer_close_widget = timer_widget
|
||||
|
||||
local notification = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
image = gears.color.recolor_image(icondir .. "notification-outline.svg",
|
||||
Theme_config.notification_center.notification_list.icon),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
right = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
markup = n.app_name or 'System Notification',
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
fg = Theme_config.notification_center.notification_list.title_fg,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
nil,
|
||||
{
|
||||
timer_widget,
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
id = "arc_app_layout_2"
|
||||
},
|
||||
id = "arc_app_layout",
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
id = "arc_app_bg",
|
||||
border_color = Theme_config.notification_center.notification_list.title_border_color,
|
||||
border_width = Theme_config.notification_center.notification_list.title_border_width,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
image = n.icon,
|
||||
resize = true,
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
clip_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, 10)
|
||||
end
|
||||
},
|
||||
width = naughty.config.defaults.icon_size,
|
||||
height = naughty.config.defaults.icon_size,
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
halign = "center",
|
||||
valign = "top",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "margin01",
|
||||
left = dpi(20),
|
||||
bottom = dpi(15),
|
||||
top = dpi(15),
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
markup = n.title,
|
||||
widget = wibox.widget.textbox,
|
||||
align = "left"
|
||||
},
|
||||
{
|
||||
markup = n.message,
|
||||
widget = wibox.widget.textbox,
|
||||
align = "left"
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
left = dpi(10),
|
||||
bottom = dpi(10),
|
||||
top = dpi(10),
|
||||
right = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "widget_layout",
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
id = "min_size",
|
||||
strategy = "min",
|
||||
width = dpi(100),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "max_size",
|
||||
strategy = "max",
|
||||
width = Theme.notification_max_width or dpi(500),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
pk = #nl.notification_list + 1,
|
||||
bg = Theme_config.notification_center.notification_list.notification_bg,
|
||||
border_color = Theme_config.notification_center.notification_list.notification_border_color,
|
||||
border_width = Theme_config.notification_center.notification_list.notification_border_width,
|
||||
shape = Theme_config.notification_center.notification_list.notification_shape,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
close_widget:connect_signal(
|
||||
"button::press",
|
||||
function(_, _, _, button)
|
||||
if button == 1 then
|
||||
for i, b in pairs(nl.notification_list) do
|
||||
if b.pk == notification.pk then
|
||||
table.remove(nl.notification_list, math.tointeger(i))
|
||||
capi.awesome.emit_signal("notification_center:update::needed")
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Hover_signal(close_widget.const.background)
|
||||
|
||||
notification:connect_signal(
|
||||
"mouse::enter",
|
||||
function()
|
||||
notification:get_children_by_id("arc_app_layout_2")[1]:set(1, close_widget)
|
||||
end
|
||||
)
|
||||
|
||||
notification:connect_signal(
|
||||
"mouse::leave",
|
||||
function()
|
||||
notification:get_children_by_id("arc_app_layout_2")[1]:set(1, timer_close_widget)
|
||||
end
|
||||
)
|
||||
|
||||
table.insert(nl.notification_list, 1, notification)
|
||||
end
|
||||
|
||||
naughty.connect_signal(
|
||||
"request::display",
|
||||
function(n)
|
||||
nl.create_notification(n)
|
||||
capi.awesome.emit_signal("notification_center:update::needed")
|
||||
end
|
||||
)
|
||||
|
||||
return nl
|
||||
@@ -1,208 +0,0 @@
|
||||
--------------------------------
|
||||
-- This is the profile widget --
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/profile/"
|
||||
|
||||
return function()
|
||||
|
||||
local profile_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
image = gears.surface.load_uncached(gears.filesystem.get_configuration_dir() ..
|
||||
"src/assets/userpfp/crylia.png"),
|
||||
id = "icon",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
clip_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(12))
|
||||
end,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "icon_margin",
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Username
|
||||
id = "username_prefix",
|
||||
image = gears.color.recolor_image(icondir .. "user.svg",
|
||||
Theme_config.notification_center.profile.username_icon_color),
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{ -- Username
|
||||
id = "username",
|
||||
valign = "center",
|
||||
align = "left",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
{
|
||||
{
|
||||
id = "os_prefix",
|
||||
image = gears.color.recolor_image(icondir .. "laptop.svg",
|
||||
Theme_config.notification_center.profile.os_prefix_icon_color),
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{ -- OS
|
||||
id = "os",
|
||||
valign = "center",
|
||||
align = "left",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
{
|
||||
{
|
||||
id = "kernel_prefix",
|
||||
image = gears.color.recolor_image(icondir .. "penguin.svg",
|
||||
Theme_config.notification_center.profile.kernel_icon_color),
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{ -- Kernel
|
||||
id = "kernel",
|
||||
valign = "center",
|
||||
align = "left",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
{
|
||||
{
|
||||
id = "uptime_prefix",
|
||||
image = gears.color.recolor_image(icondir .. "clock.svg",
|
||||
Theme_config.notification_center.profile.uptime_icon_color),
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{ -- Uptime
|
||||
id = "uptime",
|
||||
valign = "center",
|
||||
align = "left",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
spacing = dpi(10),
|
||||
id = "uptime_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
spacing = dpi(5),
|
||||
id = "info_layout",
|
||||
layout = wibox.layout.flex.vertical
|
||||
},
|
||||
id = "text_margin",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "text_container",
|
||||
bottom = dpi(20),
|
||||
left = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "text_container_wrapper",
|
||||
widget = wibox.layout.fixed.vertical
|
||||
},
|
||||
id = "wrapper",
|
||||
fg = Theme_config.notification_center.profile.fg,
|
||||
border_color = Theme_config.notification_center.profile.border_color,
|
||||
border_width = Theme_config.notification_center.profile.border_width,
|
||||
shape = Theme_config.notification_center.profile.shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "const",
|
||||
strategy = "exact",
|
||||
width = dpi(250),
|
||||
height = dpi(350),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
top = dpi(20),
|
||||
left = dpi(10),
|
||||
right = dpi(20),
|
||||
bottom = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
local function get_os_name_pretty()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"cat /etc/os-release | grep -w NAME",
|
||||
function(stdout)
|
||||
profile_widget:get_children_by_id("os")[1].text = stdout:match("\"(.+)\"")
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- function to get and set the kernel version
|
||||
local function get_kernel_version()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"uname -r",
|
||||
function(stdout)
|
||||
profile_widget:get_children_by_id("kernel")[1].text = stdout:match("(%d+%.%d+%.%d+)")
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
--function to get the username and hostname
|
||||
local function get_user_hostname()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"echo $USER@$(hostname)",
|
||||
function(stdout)
|
||||
profile_widget:get_children_by_id("username")[1].text = stdout:gsub("\n", "") or ""
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- function to fetch uptime async
|
||||
local function get_uptime()
|
||||
awful.spawn.easy_async_with_shell("uptime -p", function(stdout)
|
||||
|
||||
local hours = stdout:match("(%d+) hours") or 0
|
||||
local minutes = stdout:match("(%d+) minutes") or 0
|
||||
|
||||
profile_widget:get_children_by_id("uptime")[1].text = hours .. "h, " .. minutes .. "m"
|
||||
end)
|
||||
end
|
||||
|
||||
get_os_name_pretty()
|
||||
get_kernel_version()
|
||||
get_user_hostname()
|
||||
|
||||
gears.timer {
|
||||
timeout = 60,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = get_uptime
|
||||
}
|
||||
|
||||
return profile_widget
|
||||
|
||||
end
|
||||
@@ -1,501 +0,0 @@
|
||||
---------------------------
|
||||
-- This is the song-info --
|
||||
---------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/notifications/"
|
||||
|
||||
return function(s)
|
||||
|
||||
--#region Music control button widgets
|
||||
|
||||
local function button_hover_effect(widget, svg, color, color2)
|
||||
local mouse_enter = function()
|
||||
widget.image = gears.surface.load_uncached(gears.color.recolor_image(icondir .. svg, color2))
|
||||
local w = capi.mouse.current_wibox
|
||||
if w then
|
||||
w.cursor = "hand1"
|
||||
end
|
||||
end
|
||||
|
||||
local mouse_leave = function()
|
||||
widget.image = gears.surface.load_uncached(gears.color.recolor_image(icondir .. svg, color))
|
||||
capi.mouse.cursor = "left_ptr"
|
||||
local w = capi.mouse.current_wibox
|
||||
if w then
|
||||
w.cursor = "left_ptr"
|
||||
end
|
||||
end
|
||||
|
||||
widget:disconnect_signal("mouse::enter", mouse_enter)
|
||||
widget:connect_signal("mouse::enter", mouse_enter)
|
||||
widget:disconnect_signal("mouse::leave", mouse_leave)
|
||||
widget:connect_signal("mouse::leave", mouse_leave)
|
||||
end
|
||||
|
||||
local shuffle_button = wibox.widget {
|
||||
resize = false,
|
||||
image = gears.color.recolor_image(icondir .. "shuffle.svg",
|
||||
Theme_config.notification_center.song_info.shuffle_disabled),
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox,
|
||||
}
|
||||
|
||||
local function suffle_handler()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl shuffle",
|
||||
function(stdout)
|
||||
if stdout:match("On") then
|
||||
awful.spawn.with_shell("playerctl shuffle off")
|
||||
shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg",
|
||||
Theme_config.notification_center.song_info.shuffle_disabled)
|
||||
else
|
||||
awful.spawn.with_shell("playerctl shuffle on")
|
||||
shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg",
|
||||
Theme_config.notification_center.song_info.shuffle_enabled)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function update_shuffle()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl shuffle",
|
||||
function(stdout)
|
||||
if stdout:match("On") then
|
||||
shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg",
|
||||
Theme_config.notification_center.song_info.shuffle_enabled)
|
||||
else
|
||||
shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg",
|
||||
Theme_config.notification_center.song_info.shuffle_disabled)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
update_shuffle()
|
||||
|
||||
local repeat_button = wibox.widget {
|
||||
resize = false,
|
||||
image = gears.color.recolor_image(icondir .. "repeat.svg", Theme_config.notification_center.song_info.repeat_disabled),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "imagebox"
|
||||
}
|
||||
|
||||
-- On first time load set the correct loop
|
||||
local function update_loop()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl loop",
|
||||
function(stdout)
|
||||
local loop_mode = stdout:gsub("\n", "")
|
||||
if loop_mode == "Track" then
|
||||
repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat-once.svg"),
|
||||
Theme_config.notification_center.song_info.repeat_single)
|
||||
elseif loop_mode == "None" then
|
||||
repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat.svg"),
|
||||
Theme_config.notification_center.song_info.repeat_disabled)
|
||||
elseif loop_mode == "Playlist" then
|
||||
repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat.svg"),
|
||||
Theme_config.notification_center.song_info.repeat_all)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
update_loop()
|
||||
-- Activate shuffle when button is clicked
|
||||
shuffle_button:buttons(gears.table.join(
|
||||
awful.button({}, 1, suffle_handler)))
|
||||
|
||||
local prev_button = wibox.widget {
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "skip-prev.svg", Theme_config.notification_center.song_info.prev_enabled),
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
-- Activate previous song when button is clicked
|
||||
prev_button:buttons(gears.table.join(
|
||||
awful.button({}, 1, function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl previous && sleep 1",
|
||||
function()
|
||||
update_loop()
|
||||
end
|
||||
)
|
||||
end)
|
||||
))
|
||||
|
||||
local pause_play_button = wibox.widget {
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "play-pause.svg",
|
||||
Theme_config.notification_center.song_info.play_enabled),
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
-- Activate play/pause when button is clicked
|
||||
pause_play_button:buttons(gears.table.join(
|
||||
awful.button({}, 1, function()
|
||||
awful.spawn.with_shell("playerctl play-pause")
|
||||
end)
|
||||
))
|
||||
|
||||
local next_button = wibox.widget {
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "skip-next.svg", Theme_config.notification_center.song_info.next_enabled),
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
-- Activate next song when button is clicked
|
||||
next_button:buttons(gears.table.join(
|
||||
awful.button({}, 1, function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl next && sleep 1",
|
||||
function()
|
||||
update_loop()
|
||||
end
|
||||
)
|
||||
end)
|
||||
))
|
||||
|
||||
--- This function updates the repeat button svg and changes the mode on click
|
||||
local function loop_handler()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl loop",
|
||||
function(stdout)
|
||||
local loop_mode = stdout:gsub("\n", "")
|
||||
if loop_mode == "None" then
|
||||
awful.spawn.with_shell("playerctl loop playlist")
|
||||
repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat.svg"),
|
||||
Theme_config.notification_center.song_info.repeat_all)
|
||||
elseif loop_mode == "Playlist" then
|
||||
awful.spawn.with_shell("playerctl loop track")
|
||||
repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat-once.svg"),
|
||||
Theme_config.notification_center.song_info.repeat_single)
|
||||
elseif loop_mode == "Track" then
|
||||
awful.spawn.with_shell("playerctl loop none")
|
||||
repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat.svg"),
|
||||
Theme_config.notification_center.song_info.repeat_disabled)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
repeat_button:buttons(gears.table.join(awful.button({}, 1, loop_handler)))
|
||||
|
||||
button_hover_effect(prev_button, "skip-prev.svg", Theme_config.notification_center.song_info.prev_enabled,
|
||||
Theme_config.notification_center.song_info.prev_hover)
|
||||
button_hover_effect(pause_play_button, "play-pause.svg", Theme_config.notification_center.song_info.play_enabled,
|
||||
Theme_config.notification_center.song_info.play_hover)
|
||||
button_hover_effect(next_button, "skip-next.svg", Theme_config.notification_center.song_info.next_enabled,
|
||||
Theme_config.notification_center.song_info.next_hover)
|
||||
|
||||
--#endregion
|
||||
|
||||
-- Main music widget
|
||||
local music_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Album art
|
||||
{
|
||||
image = icondir .. "default_image.svg",
|
||||
resize = true,
|
||||
clip_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(8))
|
||||
end,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox,
|
||||
id = "imagebox"
|
||||
},
|
||||
width = dpi(80),
|
||||
height = dpi(80),
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint,
|
||||
id = "const"
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ --Title
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "textbox4"
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.title_fg,
|
||||
id = "textbox5",
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "textbox_const",
|
||||
strategy = "max",
|
||||
width = dpi(400),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
id = "textbox_container4",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{ --Artist
|
||||
halign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "textbox3"
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.artist_fg,
|
||||
id = "background",
|
||||
widget = wibox.container.background
|
||||
},
|
||||
strategy = "max",
|
||||
width = dpi(400),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
id = "artist_container",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
{ --Buttons
|
||||
{
|
||||
{
|
||||
shuffle_button,
|
||||
prev_button,
|
||||
pause_play_button,
|
||||
next_button,
|
||||
repeat_button,
|
||||
spacing = dpi(15),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
id = "layout5"
|
||||
},
|
||||
halign = "center",
|
||||
widget = wibox.container.place,
|
||||
id = "place2"
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
id = "margin6"
|
||||
},
|
||||
layout = wibox.layout.flex.vertical,
|
||||
id = "layout4"
|
||||
},
|
||||
fill_space = true,
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
id = "layout3"
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
id = "margin5"
|
||||
},
|
||||
{ --Song Duration
|
||||
{
|
||||
{
|
||||
{
|
||||
markup = "0:00",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "textbox2"
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.duration_fg,
|
||||
widget = wibox.container.background,
|
||||
id = "background3"
|
||||
},
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
id = "margin4"
|
||||
},
|
||||
{ -- Progressbar
|
||||
{
|
||||
color = Theme_config.notification_center.song_info.progress_color,
|
||||
background_color = Theme_config.notification_center.song_info.progress_background_color,
|
||||
max_value = 100,
|
||||
value = 50,
|
||||
forced_height = dpi(5),
|
||||
shape = function(cr, width)
|
||||
gears.shape.rounded_bar(cr, width, dpi(5))
|
||||
end,
|
||||
widget = wibox.widget.progressbar,
|
||||
id = "progressbar1"
|
||||
},
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place,
|
||||
id = "place1"
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
text = "00:00",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "text1"
|
||||
},
|
||||
id = "background2",
|
||||
fg = Theme_config.notification_center.song_info.duration_fg,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "margin3",
|
||||
left = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "layout2",
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
id = "layout1",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
id = "margin2",
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(10)
|
||||
},
|
||||
id = "background1",
|
||||
border_color = Theme_config.notification_center.song_info.border_color,
|
||||
border_width = Theme_config.notification_center.song_info.border_width,
|
||||
shape = Theme_config.notification_center.song_info.shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "margin1",
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(10),
|
||||
bottom = dpi(20),
|
||||
left = dpi(20),
|
||||
right = dpi(20)
|
||||
}
|
||||
|
||||
-- Used to check if the music changed and if everthing should be updated
|
||||
local trackid = ""
|
||||
local artist = ""
|
||||
local title = ""
|
||||
|
||||
-- Function to get spotify title, artist, album, album_art, length and track_id
|
||||
local function get_spotify_metadata(skip_check)
|
||||
skip_check = skip_check or false
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl metadata",
|
||||
function(stdout)
|
||||
-- Only fetch info if the track changed or if the title/artist is empty
|
||||
if skip_check or (not stdout:match(trackid)) or (not stdout:match(artist)) or (not stdout:match(title)) then
|
||||
-- Get the song title
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl metadata xesam:title",
|
||||
function(stdout2)
|
||||
local tit = stdout2:gsub("\n", "")
|
||||
title = tit
|
||||
music_widget:get_children_by_id("textbox4")[1].text = tit
|
||||
end
|
||||
)
|
||||
|
||||
-- Get the song artist
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl metadata xesam:artist",
|
||||
function(stdout2)
|
||||
local art = stdout2:gsub("\n", "")
|
||||
artist = art
|
||||
music_widget:get_children_by_id("textbox3")[1].text = art
|
||||
end
|
||||
)
|
||||
|
||||
-- Get the song album image
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl metadata mpris:artUrl",
|
||||
function(album_art)
|
||||
local url = album_art:gsub("\n", "")
|
||||
awful.spawn.easy_async_with_shell(
|
||||
-- TODO: curl does not stdout and is returns before it finished. This causes the image to sometimes not show correctly.
|
||||
-- !Find a better solution than sleep 0.1
|
||||
-- Maybe cache the image? Not sure if that would be a waste of space or not.
|
||||
"curl -s " .. url .. " -o /tmp/album_art.jpg && echo /tmp/album_art.jpg && sleep 0.5",
|
||||
function()
|
||||
music_widget:get_children_by_id("imagebox")[1].image = gears.surface.load_uncached("/tmp/album_art.jpg")
|
||||
or icondir .. "default_image.svg"
|
||||
end
|
||||
)
|
||||
end
|
||||
)
|
||||
|
||||
-- Get the length of the song
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl metadata mpris:length",
|
||||
function(stdout2)
|
||||
local length = stdout2:gsub("\n", "")
|
||||
if length ~= "" then
|
||||
local length_formated = string.format("%02d:%02d", math.floor((tonumber(length) or 1) / 60000000) or 0,
|
||||
(math.floor((tonumber(length) or 1) / 1000000) % 60) or 0)
|
||||
music_widget:get_children_by_id("progressbar1")[1].max_value = tonumber(math.floor(tonumber(length) /
|
||||
1000000))
|
||||
music_widget:get_children_by_id("text1")[1].markup = string.format("<span foreground='%s' font='JetBrainsMono Nerd Font, Bold 14'>%s</span>"
|
||||
, Theme_config.notification_center.song_info.duration_fg, length_formated)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl metadata mpris:trackid",
|
||||
function(stdout2)
|
||||
trackid = stdout2:gsub("\n", "")
|
||||
end
|
||||
)
|
||||
-- Update track id
|
||||
trackid, artist, title = stdout, music_widget:get_children_by_id("textbox3")[1].text,
|
||||
music_widget:get_children_by_id("textbox4")[1].text
|
||||
end
|
||||
)
|
||||
-- Always update the current song progression
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl position",
|
||||
function(stdout)
|
||||
local time = stdout:gsub("\n", "")
|
||||
if time ~= "" then
|
||||
local time_formated = string.format("%02d:%02d", math.floor((tonumber(time) or 1) / 60),
|
||||
math.floor(tonumber(time) or 1) % 60)
|
||||
music_widget:get_children_by_id("textbox2")[1].markup = string.format("<span foreground='%s' font='JetBrainsMono Nerd Font, Bold 14'>%s</span>"
|
||||
, Theme_config.notification_center.song_info.duration_fg, time_formated)
|
||||
music_widget:get_children_by_id("progressbar1")[1].value = tonumber(time)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- Call every second, if performance is bad, set the timer to a higher value
|
||||
gears.timer {
|
||||
timeout = 1,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
--!Rewrite entire playerctl module for better performance
|
||||
--get_spotify_metadata()
|
||||
end
|
||||
}
|
||||
|
||||
-- get_spotify_metadata() on awesome reload
|
||||
capi.awesome.connect_signal("startup", function()
|
||||
get_spotify_metadata(true)
|
||||
end)
|
||||
|
||||
return music_widget
|
||||
end
|
||||
@@ -1,22 +0,0 @@
|
||||
------------------------------------------------
|
||||
-- This is the spacing widget under the clock --
|
||||
------------------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local wibox = require("wibox")
|
||||
|
||||
return function()
|
||||
|
||||
return wibox.widget {
|
||||
{
|
||||
forced_height = dpi(2),
|
||||
bg = Theme_config.notification_center.spacing_line.color,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
left = dpi(80),
|
||||
right = dpi(80),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
end
|
||||
@@ -1,840 +0,0 @@
|
||||
------------------------------------
|
||||
-- This is the status_bars widget --
|
||||
------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local rubato = require("src.lib.rubato")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/"
|
||||
|
||||
--- Signal bars widget for the notification-center
|
||||
---@diagnostic disable-next-line: undefined-doc-name
|
||||
---@return wibox.widget
|
||||
return function()
|
||||
|
||||
---Creates a layout with bar widgets based on the given table
|
||||
---@param widget_table table
|
||||
---@return table
|
||||
local function create_bar_layout(widget_table)
|
||||
local bar_layout = { layout = wibox.layout.flex.horizontal, spacing = dpi(10) }
|
||||
|
||||
for _, widget in pairs(widget_table) do
|
||||
local w
|
||||
if widget == "cpu_usage" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.cpu_usage_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
image = gears.color.recolor_image(icondir .. "cpu/cpu.svg",
|
||||
Theme_config.notification_center.status_bar.cpu_usage_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox,
|
||||
id = "icon1",
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "cpu_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"update::cpu_usage",
|
||||
function(cpu_usage)
|
||||
tooltip.text = "CPU Usage: " .. cpu_usage .. "%"
|
||||
rubato_timer.target = cpu_usage
|
||||
end
|
||||
)
|
||||
elseif widget == "cpu_temp" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.cpu_temp_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = "icon1",
|
||||
image = gears.color.recolor_image(icondir .. "cpu/thermometer.svg",
|
||||
Theme_config.notification_center.status_bar.cpu_temp_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "cpu_temp_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"update::cpu_temp",
|
||||
function(cpu_temp)
|
||||
local temp_icon
|
||||
if cpu_temp < 50 then
|
||||
temp_icon = icondir .. "cpu/thermometer-low.svg"
|
||||
elseif cpu_temp >= 50 and cpu_temp < 80 then
|
||||
temp_icon = icondir .. "cpu/thermometer.svg"
|
||||
elseif cpu_temp >= 80 then
|
||||
temp_icon = icondir .. "cpu/thermometer-high.svg"
|
||||
end
|
||||
w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(temp_icon,
|
||||
Theme_config.notification_center.status_bar.cpu_temp_color)
|
||||
tooltip.text = "CPU Temp: " .. cpu_temp .. "°C"
|
||||
rubato_timer.target = cpu_temp
|
||||
end
|
||||
)
|
||||
elseif widget == "ram_usage" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.ram_usage_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
image = gears.color.recolor_image(icondir .. "cpu/ram.svg",
|
||||
Theme_config.notification_center.status_bar.ram_usage_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "ram_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"update::ram_widget",
|
||||
function(MemTotal, _, MemAvailable)
|
||||
if not MemTotal or not MemAvailable then
|
||||
return
|
||||
end
|
||||
local ram_usage = math.floor(((MemTotal - MemAvailable) / MemTotal * 100) + 0.5)
|
||||
tooltip.text = "RAM Usage: " .. ram_usage .. "%"
|
||||
rubato_timer.target = ram_usage
|
||||
end
|
||||
)
|
||||
elseif widget == "gpu_usage" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.gpu_usage_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
image = gears.color.recolor_image(icondir .. "cpu/gpu.svg",
|
||||
Theme_config.notification_center.status_bar.gpu_usage_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "gpu_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"update::gpu_usage",
|
||||
function(gpu_usage)
|
||||
if not gpu_usage then return end
|
||||
tooltip.text = "GPU Usage: " .. gpu_usage .. "%"
|
||||
rubato_timer.target = tonumber(gpu_usage)
|
||||
end
|
||||
)
|
||||
elseif widget == "gpu_temp" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.gpu_temp_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = "icon1",
|
||||
image = gears.color.recolor_image(icondir .. "cpu/thermometer.svg",
|
||||
Theme_config.notification_center.status_bar.gpu_temp_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "gpu_temp_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"update::gpu_temp",
|
||||
function(gpu_temp)
|
||||
local temp_icon
|
||||
local temp_num = tonumber(gpu_temp) or "NaN"
|
||||
|
||||
if temp_num then
|
||||
|
||||
if temp_num < 50 then
|
||||
temp_icon = icondir .. "cpu/thermometer-low.svg"
|
||||
elseif temp_num >= 50 and temp_num < 80 then
|
||||
temp_icon = icondir .. "cpu/thermometer.svg"
|
||||
elseif temp_num >= 80 then
|
||||
temp_icon = icondir .. "cpu/thermometer-high.svg"
|
||||
end
|
||||
else
|
||||
temp_num = "NaN"
|
||||
temp_icon = icondir .. "cpu/thermometer-low.svg"
|
||||
end
|
||||
w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(temp_icon,
|
||||
Theme_config.notification_center.status_bar.gpu_temp_color)
|
||||
tooltip.text = "GPU Temp: " .. temp_num .. "°C"
|
||||
rubato_timer.target = temp_num
|
||||
end
|
||||
)
|
||||
elseif widget == "volume" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.volume_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = "icon1",
|
||||
image = gears.color.recolor_image(icondir .. "audio/volume-high.svg",
|
||||
Theme_config.notification_center.status_bar.volume_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "volume_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"audio::get",
|
||||
function(muted, volume)
|
||||
local icon = icondir .. "audio/volume"
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
if muted then
|
||||
icon = icon .. "-mute"
|
||||
else
|
||||
if volume < 1 then
|
||||
icon = icon .. "-mute"
|
||||
elseif volume >= 1 and volume < 34 then
|
||||
icon = icon .. "-low"
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. "-medium"
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. "-high"
|
||||
end
|
||||
end
|
||||
w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(icon .. ".svg",
|
||||
Theme_config.notification_center.status_bar.volume_color)
|
||||
tooltip.text = "Volume: " .. volume .. "%"
|
||||
rubato_timer.target = volume
|
||||
end
|
||||
)
|
||||
elseif widget == "microphone" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.microphone_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = "icon1",
|
||||
image = gears.color.recolor_image(icondir .. "audio/microphone.svg",
|
||||
Theme_config.notification_center.status_bar.microphone_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "microphone_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"microphone::get",
|
||||
function(muted, volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
local icon = icondir .. "audio/microphone"
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
if muted or (volume < 1) then
|
||||
icon = icon .. "-off"
|
||||
end
|
||||
w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(icon .. ".svg",
|
||||
Theme_config.notification_center.status_bar.microphone_color)
|
||||
tooltip.text = "Microphone: " .. volume .. "%"
|
||||
rubato_timer.target = volume
|
||||
end
|
||||
)
|
||||
elseif widget == "backlight" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.backlight_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = "icon1",
|
||||
image = gears.color.recolor_image(icondir .. "brightness/brightness-high.svg",
|
||||
Theme_config.notification_center.status_bar.backlight_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "brightness_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"brightness::get",
|
||||
function(brightness)
|
||||
local icon = icondir .. "brightness"
|
||||
if brightness >= 0 and brightness < 34 then
|
||||
icon = icon .. "-low"
|
||||
elseif brightness >= 34 and brightness < 67 then
|
||||
icon = icon .. "-medium"
|
||||
elseif brightness >= 67 then
|
||||
icon = icon .. "-high"
|
||||
end
|
||||
w:get_children_by_id("icon1")[1]:set_image(gears.color.recolor_image(icon .. ".svg",
|
||||
Theme_config.notification_center.status_bar.backlight_color))
|
||||
tooltip.text = "Backlight: " .. brightness .. "%"
|
||||
rubato_timer.target = brightness
|
||||
end
|
||||
)
|
||||
elseif widget == "battery" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.battery_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = "icon1",
|
||||
image = gears.color.recolor_image(icondir .. "battery/battery.svg",
|
||||
Theme_config.notification_center.status_bar.battery_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "battery_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"update::battery_widget",
|
||||
function(battery, battery_icon)
|
||||
w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(battery_icon,
|
||||
Theme_config.notification_center.status_bar.battery_color)
|
||||
tooltip.text = "Battery: " .. battery .. "%"
|
||||
rubato_timer.target = battery
|
||||
end
|
||||
)
|
||||
end
|
||||
table.insert(bar_layout, w)
|
||||
end
|
||||
|
||||
return bar_layout
|
||||
end
|
||||
|
||||
local signal_bars = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
create_bar_layout(User_config.status_bar_widgets),
|
||||
width = dpi(480),
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
magins = dpi(10),
|
||||
layout = wibox.container.margin
|
||||
},
|
||||
forced_height = dpi(120),
|
||||
forced_width = dpi(500),
|
||||
border_color = Theme_config.notification_center.status_bar.border_color,
|
||||
border_width = Theme_config.notification_center.status_bar.border_width,
|
||||
shape = Theme_config.notification_center.status_bar.shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
top = dpi(10),
|
||||
left = dpi(20),
|
||||
right = dpi(20),
|
||||
bottom = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
return signal_bars
|
||||
|
||||
end
|
||||
@@ -1,65 +0,0 @@
|
||||
----------------------------------
|
||||
-- This is the time_date widget --
|
||||
----------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local wibox = require("wibox")
|
||||
|
||||
return function()
|
||||
|
||||
local time_date = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Time
|
||||
{
|
||||
id = "label",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
format = "<span foreground='#18FFFF' font='JetBrainsMono Nerd Font, Bold 46'><b>%H:%M</b></span>",
|
||||
widget = wibox.widget.textclock
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{ -- Date and Day
|
||||
{ -- Date
|
||||
{
|
||||
id = "label",
|
||||
align = "left",
|
||||
valign = "bottom",
|
||||
format = "<span foreground='#69F0AE' font='JetBrainsMono Nerd Font, Regular 18'><b>%d</b></span><span foreground='#18FFFF' font='JetBrainsMono Nerd Font, Regular 18'><b> %b %Y</b></span>",
|
||||
widget = wibox.widget.textclock
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{ -- Day
|
||||
{
|
||||
id = "label",
|
||||
align = "left",
|
||||
valign = "top",
|
||||
format = "<span foreground='#69F0AE' font='JetBrainsMono Nerd Font, Bold 20'><b>%A</b></span>",
|
||||
widget = wibox.widget.textclock
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
layout = wibox.layout.flex.vertical
|
||||
},
|
||||
spacing = dpi(20),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background",
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "margin",
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
return time_date
|
||||
|
||||
end
|
||||
@@ -1,224 +0,0 @@
|
||||
--------------------------------
|
||||
-- This is the weather widget --
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local naughty = require("naughty")
|
||||
|
||||
local json_lua = require("src.lib.json-lua.json-lua")
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/weather/"
|
||||
|
||||
return function()
|
||||
|
||||
local api_secrets = {
|
||||
key = User_config.weather_secrets.key,
|
||||
city_id = User_config.weather_secrets.city_id,
|
||||
unit = User_config.weather_secrets.unit
|
||||
}
|
||||
|
||||
local weather_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Icon
|
||||
valign = "center",
|
||||
align = "center",
|
||||
resize = true,
|
||||
forced_width = dpi(64),
|
||||
forced_height = dpi(64),
|
||||
widget = wibox.widget.imagebox,
|
||||
id = "icon"
|
||||
},
|
||||
id = "place2",
|
||||
valing = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
{ -- Temperature
|
||||
text = "0°C",
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
font = "JetBrains Mono Bold 24",
|
||||
id = "temp"
|
||||
},
|
||||
{ -- City, Country
|
||||
text = "City, Country",
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "city_country",
|
||||
},
|
||||
{
|
||||
{ -- Description
|
||||
text = "Description",
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "description"
|
||||
},
|
||||
fg = Theme_config.notification_center.weather.description_fg,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
{ -- line
|
||||
forced_height = dpi(4),
|
||||
forced_width = dpi(10),
|
||||
bg = Theme_config.notification_center.weather.line_bg,
|
||||
widget = wibox.container.background,
|
||||
id = "line"
|
||||
},
|
||||
{
|
||||
{ -- Speed
|
||||
{
|
||||
image = gears.color.recolor_image(icondir .. "weather-windy.svg",
|
||||
Theme_config.notification_center.weather.speed_icon_color),
|
||||
resize = true,
|
||||
forced_width = dpi(24),
|
||||
forced_height = dpi(24),
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{
|
||||
text = "",
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "speed"
|
||||
},
|
||||
spacing = dpi(10),
|
||||
id = "layout3",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "place4",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
{
|
||||
{ -- Humidity
|
||||
{
|
||||
forced_width = dpi(24),
|
||||
forced_height = dpi(24),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "humidity.svg",
|
||||
Theme_config.notification_center.weather.humidity_icon_color),
|
||||
id = "humidity_icon"
|
||||
},
|
||||
{
|
||||
text = "",
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "humidity"
|
||||
},
|
||||
spacing = dpi(10),
|
||||
id = "layoutHum",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "lyt",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "center",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background",
|
||||
border_color = Theme_config.notification_center.weather.border_color,
|
||||
border_width = Theme_config.notification_center.weather.border_width,
|
||||
shape = Theme_config.notification_center.weather.shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "margin",
|
||||
top = dpi(20),
|
||||
left = dpi(20),
|
||||
right = dpi(10),
|
||||
bottom = dpi(10),
|
||||
forced_width = dpi(250),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
local function fetch_weather_data()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"curl -sf 'http://api.openweathermap.org/data/2.5/weather?id=" ..
|
||||
api_secrets.city_id .. "&units=" .. api_secrets.unit .. "&appid=" .. api_secrets.key .. "'",
|
||||
function(stdout)
|
||||
if not stdout:match('error') then
|
||||
local weather_metadata = json_lua:decode(stdout)
|
||||
if weather_metadata then
|
||||
local temp = weather_metadata.main.temp
|
||||
local humidity = weather_metadata.main.humidity
|
||||
local city = weather_metadata.name
|
||||
local country = weather_metadata.sys.country
|
||||
local weather_icon = weather_metadata.weather[1].icon
|
||||
local description = weather_metadata.weather[1].description
|
||||
local speed = weather_metadata.wind.speed
|
||||
|
||||
local icon_table = {
|
||||
["01d"] = "weather-sunny",
|
||||
["01n"] = "weather-clear-night",
|
||||
["02d"] = "weather-partly-cloudy",
|
||||
["02n"] = "weather-night-partly-cloudy",
|
||||
["03d"] = "weather-cloudy",
|
||||
["03n"] = "weather-clouds-night",
|
||||
["04d"] = "weather-cloudy",
|
||||
["04n"] = "weather-cloudy",
|
||||
["09d"] = "weather-rainy",
|
||||
["09n"] = "weather-rainy",
|
||||
["10d"] = "weather-partly-rainy",
|
||||
["10n"] = "weather-partly-rainy",
|
||||
["11d"] = "weather-pouring",
|
||||
["11n"] = "weather-pouring",
|
||||
["13d"] = "weather-snowy",
|
||||
["13n"] = "weather-snowy",
|
||||
["50d"] = "weather-fog",
|
||||
["50n"] = "weather-fog"
|
||||
}
|
||||
|
||||
weather_widget:get_children_by_id("icon")[1].image = icondir .. icon_table[weather_icon] .. ".svg"
|
||||
weather_widget:get_children_by_id("temp")[1].text = math.floor(temp + 0.5) .. "°C"
|
||||
weather_widget:get_children_by_id("city_country")[1].text = city .. ", " .. country
|
||||
weather_widget:get_children_by_id("description")[1].text = description:sub(1, 1):upper() ..
|
||||
description:sub(2)
|
||||
weather_widget:get_children_by_id("line")[1].bg = Theme_config.notification_center.weather.line_color
|
||||
weather_widget:get_children_by_id("speed")[1].text = speed .. " m/s"
|
||||
weather_widget:get_children_by_id("humidity")[1].text = humidity .. "%"
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
fetch_weather_data()
|
||||
|
||||
gears.timer {
|
||||
timeout = 900,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
fetch_weather_data()
|
||||
end
|
||||
}
|
||||
|
||||
return weather_widget
|
||||
|
||||
end
|
||||
@@ -0,0 +1,71 @@
|
||||
-------------------------------------
|
||||
-- This is the notification-center --
|
||||
-------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
local naughty = require('naughty')
|
||||
local gtimer = require('gears.timer')
|
||||
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
return setmetatable({}, {
|
||||
__call = function()
|
||||
local ret = wibox.widget {
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
step = dpi(100),
|
||||
spacing = dpi(20),
|
||||
}
|
||||
|
||||
--!No, :get_children_by_id() does not work here for some reason, yes I hate it too
|
||||
--[[ naughty.connect_signal('notification_surface', function(b)
|
||||
local start_time = os.time()
|
||||
local w = wibox.template.make_from_value(b)
|
||||
w = w:get_widget()
|
||||
assert(type(w) == 'table', 'w is not a wibox.widget.base')
|
||||
|
||||
-- Change the clock to a timer how long ago the notification was created
|
||||
w.children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[1] = wibox.widget {
|
||||
text = 'now',
|
||||
font = 'JetBrainsMono Nerd Font, Bold 12',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
}
|
||||
|
||||
hover.bg_hover { widget = w.children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[2].children[1].children[1] }
|
||||
w.children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[2]:connect_signal('button::press', function()
|
||||
ret:remove_widgets(w)
|
||||
ret:emit_signal('new_children')
|
||||
end)
|
||||
|
||||
gtimer {
|
||||
timeout = 1,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
local time_ago = math.floor(os.time() - start_time)
|
||||
local timer_text = w.children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[1]
|
||||
if time_ago < 5 then
|
||||
timer_text:set_text('now')
|
||||
elseif time_ago < 60 then
|
||||
timer_text:set_text(time_ago .. 's ago')
|
||||
elseif time_ago < 3600 then
|
||||
timer_text:set_text(math.floor(time_ago / 60) .. 'm ago')
|
||||
elseif time_ago < 86400 then
|
||||
timer_text:set_text(math.floor(time_ago / 3600) .. 'h ago')
|
||||
else
|
||||
timer_text:set_text(math.floor(time_ago / 86400) .. 'd ago')
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
ret:add(w)
|
||||
ret:emit_signal('new_children')
|
||||
end) ]]
|
||||
|
||||
return ret
|
||||
end,
|
||||
})
|
||||
174
awesome/src/modules/notification-center/widgets/profile.lua
Normal file
174
awesome/src/modules/notification-center/widgets/profile.lua
Normal file
@@ -0,0 +1,174 @@
|
||||
--------------------------------
|
||||
-- This is the profile widget --
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local aspawn = require('awful.spawn')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gshape = require('gears.shape')
|
||||
local gsurface = require('gears.surface')
|
||||
local gtimer = require('gears.timer')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/profile/'
|
||||
|
||||
local instance = nil
|
||||
|
||||
if not instance then
|
||||
instance = setmetatable({}, { __call = function()
|
||||
local w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
image = gsurface.load_uncached(gfilesystem.get_configuration_dir() .. 'src/assets/userpfp/userpfp.png'),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
clip_shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(12))
|
||||
end,
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Username
|
||||
image = gcolor.recolor_image(icondir .. 'user.svg',
|
||||
Theme_config.notification_center.profile.username_icon_color),
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{ -- Username
|
||||
id = 'username',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. 'laptop.svg',
|
||||
Theme_config.notification_center.profile.os_prefix_icon_color),
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{ -- OS
|
||||
id = 'os',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. 'penguin.svg',
|
||||
Theme_config.notification_center.profile.kernel_icon_color),
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{ -- Kernel
|
||||
id = 'kernel',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. 'clock.svg',
|
||||
Theme_config.notification_center.profile.uptime_icon_color),
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{ -- Uptime
|
||||
id = 'uptime',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
spacing = dpi(5),
|
||||
layout = wibox.layout.flex.vertical,
|
||||
},
|
||||
bottom = dpi(20),
|
||||
left = dpi(20),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.layout.fixed.vertical,
|
||||
},
|
||||
fg = Theme_config.notification_center.profile.fg,
|
||||
border_color = Theme_config.notification_center.profile.border_color,
|
||||
border_width = Theme_config.notification_center.profile.border_width,
|
||||
shape = Theme_config.notification_center.profile.shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
strategy = 'exact',
|
||||
width = dpi(250),
|
||||
height = dpi(350),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
top = dpi(20),
|
||||
left = dpi(10),
|
||||
right = dpi(20),
|
||||
bottom = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
}
|
||||
|
||||
aspawn.easy_async_with_shell('cat /etc/os-release | grep -w NAME', function(stdout)
|
||||
w:get_children_by_id('os')[1].text = stdout:match('\"(.+)\"')
|
||||
end)
|
||||
|
||||
aspawn.easy_async_with_shell('uname -r', function(stdout)
|
||||
w:get_children_by_id('kernel')[1].text = stdout:match('(%d+%.%d+%.%d+)')
|
||||
end)
|
||||
|
||||
aspawn.easy_async_with_shell('echo $USER@$(hostname)', function(stdout)
|
||||
w:get_children_by_id('username')[1].text = stdout:gsub('\n', '') or ''
|
||||
end)
|
||||
|
||||
gtimer {
|
||||
timeout = 60,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
aspawn.easy_async_with_shell('uptime -p', function(stdout)
|
||||
local hours = stdout:match('(%d+) hours') or 0
|
||||
local minutes = stdout:match('(%d+) minutes') or 0
|
||||
w:get_children_by_id('uptime')[1].text = hours .. 'h, ' .. minutes .. 'm'
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
return w
|
||||
end, })
|
||||
end
|
||||
|
||||
return instance
|
||||
241
awesome/src/modules/notification-center/widgets/song_info.lua
Normal file
241
awesome/src/modules/notification-center/widgets/song_info.lua
Normal file
@@ -0,0 +1,241 @@
|
||||
---------------------------
|
||||
-- This is the song-info --
|
||||
---------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gtable = require('gears.table')
|
||||
local gcolor = require('gears.color')
|
||||
local gshape = require('gears.shape')
|
||||
local base = require('wibox.widget.base')
|
||||
local abutton = require('awful.button')
|
||||
|
||||
local mh = require('src.tools.helpers.playerctl')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/'
|
||||
|
||||
local music_player = {}
|
||||
|
||||
return setmetatable({}, { __call = function()
|
||||
local w = base.make_widget_from_value {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Album art
|
||||
{
|
||||
image = icondir .. 'default_image.svg',
|
||||
resize = true,
|
||||
clip_shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(8))
|
||||
end,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
id = 'album_art',
|
||||
},
|
||||
width = dpi(80),
|
||||
height = dpi(80),
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ --Title
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
text = 'Unknown Title',
|
||||
id = 'title',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.title_fg,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
strategy = 'max',
|
||||
width = dpi(400),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{ --Artist
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
id = 'artist',
|
||||
text = 'Unknown Artist',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.artist_fg,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
strategy = 'max',
|
||||
width = dpi(400),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{ --Buttons
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. 'shuffle.svg',
|
||||
Theme_config.notification_center.song_info.shuffle_disabled),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'shuffle',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{
|
||||
resize = false,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'prev',
|
||||
image = gcolor.recolor_image(icondir .. 'skip-prev.svg', Theme_config.notification_center.song_info.prev_enabled),
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{
|
||||
resize = false,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'play_pause',
|
||||
image = gcolor.recolor_image(icondir .. 'play-pause.svg',
|
||||
Theme_config.notification_center.song_info.play_enabled),
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{
|
||||
resize = false,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'next',
|
||||
image = gcolor.recolor_image(icondir .. 'skip-next.svg', Theme_config.notification_center.song_info.next_enabled),
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. 'repeat.svg', Theme_config.notification_center.song_info.repeat_disabled),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'repeat',
|
||||
},
|
||||
spacing = dpi(15),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
layout = wibox.layout.flex.vertical,
|
||||
},
|
||||
fill_space = true,
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{ --Song Duration
|
||||
{
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'position',
|
||||
text = '00:00',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.duration_fg,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{ -- Progressbar
|
||||
{
|
||||
color = Theme_config.notification_center.song_info.progress_color,
|
||||
background_color = Theme_config.notification_center.song_info.progress_background_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
id = 'progress',
|
||||
forced_height = dpi(5),
|
||||
shape = function(cr, width)
|
||||
gshape.rounded_bar(cr, width, dpi(5))
|
||||
end,
|
||||
widget = wibox.widget.progressbar,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'length',
|
||||
text = '00:00',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.duration_fg,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
left = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(10),
|
||||
},
|
||||
border_color = Theme_config.notification_center.song_info.border_color,
|
||||
border_width = Theme_config.notification_center.song_info.border_width,
|
||||
shape = Theme_config.notification_center.song_info.shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(10),
|
||||
bottom = dpi(20),
|
||||
left = dpi(20),
|
||||
right = dpi(20),
|
||||
}
|
||||
assert(type(w) == 'table', 'Widget must be a table')
|
||||
|
||||
gtable.crush(w, music_player, true)
|
||||
|
||||
local music_handler = mh(w)
|
||||
|
||||
--#region Buttons
|
||||
w:get_children_by_id('play_pause')[1]:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
music_handler:play_pause()
|
||||
end)
|
||||
))
|
||||
|
||||
w:get_children_by_id('next')[1]:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
music_handler:next()
|
||||
end)
|
||||
))
|
||||
|
||||
w:get_children_by_id('prev')[1]:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
music_handler:prev()
|
||||
end)
|
||||
))
|
||||
|
||||
w:get_children_by_id('repeat')[1]:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
music_handler:set_loop_status()
|
||||
end)
|
||||
))
|
||||
|
||||
w:get_children_by_id('shuffle')[1]:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
music_handler:set_shuffle()
|
||||
end)
|
||||
))
|
||||
--#endregion
|
||||
return w
|
||||
end, })
|
||||
266
awesome/src/modules/notification-center/widgets/status_bars.lua
Normal file
266
awesome/src/modules/notification-center/widgets/status_bars.lua
Normal file
@@ -0,0 +1,266 @@
|
||||
------------------------------------
|
||||
-- This is the status_bars widget --
|
||||
------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gears = require('gears')
|
||||
local wibox = require('wibox')
|
||||
local base = require('wibox.widget.base')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
|
||||
local rubato = require('src.lib.rubato')
|
||||
|
||||
-- Own Libs
|
||||
local audio = require('src.tools.helpers.audio')
|
||||
local backlight = require('src.tools.helpers.backlight')
|
||||
--local battery = require('src.tools.helpers.battery')
|
||||
local cpu_usage = require('src.tools.helpers.cpu_usage')
|
||||
local cpu_temp = require('src.tools.helpers.cpu_temp')
|
||||
local ram = require('src.tools.helpers.ram')
|
||||
local gpu_usage = require('src.tools.helpers.gpu_usage')
|
||||
local gpu_temp = require('src.tools.helpers.gpu_temp')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/'
|
||||
|
||||
return setmetatable({}, { __call = function()
|
||||
|
||||
---Creates a layout with bar widgets based on the given table
|
||||
---@param widget_table table
|
||||
---@return table
|
||||
local function create_bar_layout(widget_table)
|
||||
local bar_layout = { layout = wibox.layout.flex.horizontal, spacing = dpi(10) }
|
||||
|
||||
for _, widget in pairs(widget_table) do
|
||||
local w = base.make_widget_from_value {
|
||||
{
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.cpu_usage_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = 'progress_role',
|
||||
widget = wibox.widget.progressbar,
|
||||
},
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
direction = 'east',
|
||||
widget = wibox.container.rotate,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
width = dpi(24),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = 'image_role',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
}
|
||||
|
||||
assert(type(w) == 'table', 'Widget creation failed')
|
||||
|
||||
local bar = w:get_children_by_id('progress_role')[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end,
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = 'inside',
|
||||
preferred_alignments = 'middle',
|
||||
margins = dpi(10),
|
||||
}
|
||||
|
||||
if widget == 'cpu_usage' then
|
||||
cpu_usage:connect_signal('update::cpu_usage', function(_, v)
|
||||
tooltip.text = 'CPU Usage: ' .. v .. '%'
|
||||
rubato_timer.target = v
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/cpu.svg',
|
||||
Theme_config.notification_center.status_bar.cpu_usage_color)
|
||||
end)
|
||||
elseif widget == 'cpu_temp' then
|
||||
cpu_temp:connect_signal('update::cpu_temp', function(_, v)
|
||||
local temp_icon
|
||||
if v < 50 then
|
||||
temp_icon = icondir .. 'cpu/thermometer-low.svg'
|
||||
elseif v >= 50 and v < 80 then
|
||||
temp_icon = icondir .. 'cpu/thermometer.svg'
|
||||
elseif v >= 80 then
|
||||
temp_icon = icondir .. 'cpu/thermometer-high.svg'
|
||||
end
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(temp_icon,
|
||||
Theme_config.notification_center.status_bar.cpu_temp_color)
|
||||
tooltip.text = 'CPU Temp: ' .. v .. '°C'
|
||||
rubato_timer.target = v
|
||||
end)
|
||||
elseif widget == 'ram_usage' then
|
||||
ram:connect_signal('update::ram_widget', function(_, MemTotal, _, MemAvailable)
|
||||
if not MemTotal or not MemAvailable then return end
|
||||
local ram_usage = math.floor(((MemTotal - MemAvailable) / MemTotal * 100) + 0.5)
|
||||
tooltip.text = 'RAM Usage: ' .. ram_usage .. '%'
|
||||
rubato_timer.target = ram_usage
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/ram.svg',
|
||||
Theme_config.notification_center.status_bar.ram_usage_color)
|
||||
end)
|
||||
elseif widget == 'gpu_usage' then
|
||||
gpu_usage:connect_signal('update::gpu_usage', function(_, v)
|
||||
if not v then return end
|
||||
tooltip.text = 'GPU Usage: ' .. v .. '%'
|
||||
rubato_timer.target = tonumber(v)
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/gpu.svg',
|
||||
Theme_config.notification_center.status_bar.gpu_usage_color)
|
||||
end)
|
||||
elseif widget == 'gpu_temp' then
|
||||
gpu_temp:connect_signal('update::gpu_temp', function(_, v)
|
||||
local temp_icon, temp_num
|
||||
|
||||
if v then
|
||||
temp_num = tonumber(v)
|
||||
if temp_num < 50 then
|
||||
temp_icon = icondir .. 'cpu/thermometer-low.svg'
|
||||
elseif temp_num >= 50 and temp_num < 80 then
|
||||
temp_icon = icondir .. 'cpu/thermometer.svg'
|
||||
elseif temp_num >= 80 then
|
||||
temp_icon = icondir .. 'cpu/thermometer-high.svg'
|
||||
end
|
||||
else
|
||||
temp_num = 'NaN'
|
||||
temp_icon = icondir .. 'cpu/thermometer-low.svg'
|
||||
end
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(temp_icon,
|
||||
Theme_config.notification_center.status_bar.gpu_temp_color)
|
||||
tooltip.text = 'GPU Temp: ' .. temp_num .. '°C'
|
||||
rubato_timer.target = temp_num
|
||||
end)
|
||||
elseif widget == 'volume' then
|
||||
audio:connect_signal('sink::get', function(_, muted, volume)
|
||||
local icon = icondir .. 'audio/volume'
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
if muted then
|
||||
icon = icon .. '-mute'
|
||||
else
|
||||
if volume < 1 then
|
||||
icon = icon .. '-mute'
|
||||
elseif volume >= 1 and volume < 34 then
|
||||
icon = icon .. '-low'
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. '-medium'
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. '-high'
|
||||
end
|
||||
end
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icon .. '.svg',
|
||||
Theme_config.notification_center.status_bar.volume_color)
|
||||
tooltip.text = 'Volume: ' .. volume .. '%'
|
||||
rubato_timer.target = volume
|
||||
end)
|
||||
elseif widget == 'microphone' then
|
||||
audio:connect_signal('source::get', function(_, muted, volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
local icon = icondir .. 'audio/microphone'
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
if muted or (volume < 1) then
|
||||
icon = icon .. '-off'
|
||||
end
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icon .. '.svg',
|
||||
Theme_config.notification_center.status_bar.microphone_color)
|
||||
tooltip.text = 'Microphone: ' .. volume .. '%'
|
||||
rubato_timer.target = volume
|
||||
end)
|
||||
elseif widget == 'backlight' then
|
||||
backlight:connect_signal('brightness::get', function(_, v)
|
||||
local icon = icondir .. 'brightness'
|
||||
if v >= 0 and v < 34 then
|
||||
icon = icon .. '-low'
|
||||
elseif v >= 34 and v < 67 then
|
||||
icon = icon .. '-medium'
|
||||
elseif v >= 67 then
|
||||
icon = icon .. '-high'
|
||||
end
|
||||
w:get_children_by_id('image_role')[1]:set_image(gears.color.recolor_image(icon .. '.svg',
|
||||
Theme_config.notification_center.status_bar.backlight_color))
|
||||
tooltip.text = 'Backlight: ' .. v .. '%'
|
||||
rubato_timer.target = v
|
||||
end)
|
||||
elseif widget == 'battery' then
|
||||
--[[ battery:connect_signal('update::battery_widget', function(battery, battery_icon)
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(battery_icon,
|
||||
Theme_config.notification_center.status_bar.battery_color)
|
||||
tooltip.text = 'Battery: ' .. battery .. '%'
|
||||
rubato_timer.target = battery
|
||||
end) ]]
|
||||
end
|
||||
table.insert(bar_layout, w)
|
||||
end
|
||||
|
||||
return bar_layout
|
||||
end
|
||||
|
||||
return wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
create_bar_layout(User_config.status_bar_widgets),
|
||||
width = dpi(480),
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
magins = dpi(10),
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
border_color = Theme_config.notification_center.status_bar.border_color,
|
||||
border_width = Theme_config.notification_center.status_bar.border_width,
|
||||
shape = Theme_config.notification_center.status_bar.shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(120),
|
||||
width = dpi(500),
|
||||
strategy = 'exact',
|
||||
},
|
||||
top = dpi(10),
|
||||
left = dpi(20),
|
||||
right = dpi(20),
|
||||
bottom = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
}
|
||||
|
||||
end, })
|
||||
203
awesome/src/modules/notification-center/widgets/weather.lua
Normal file
203
awesome/src/modules/notification-center/widgets/weather.lua
Normal file
@@ -0,0 +1,203 @@
|
||||
--------------------------------
|
||||
-- This is the weather widget --
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gtimer = require('gears.timer')
|
||||
local aspawn = require('awful.spawn')
|
||||
local gcolor = require('gears.color')
|
||||
|
||||
local json_lua = require('src.lib.json-lua.json-lua')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/weather/'
|
||||
|
||||
local instance = nil
|
||||
|
||||
local icon_table = {
|
||||
['01d'] = 'weather-sunny',
|
||||
['01n'] = 'weather-clear-night',
|
||||
['02d'] = 'weather-partly-cloudy',
|
||||
['02n'] = 'weather-night-partly-cloudy',
|
||||
['03d'] = 'weather-cloudy',
|
||||
['03n'] = 'weather-clouds-night',
|
||||
['04d'] = 'weather-cloudy',
|
||||
['04n'] = 'weather-cloudy',
|
||||
['09d'] = 'weather-rainy',
|
||||
['09n'] = 'weather-rainy',
|
||||
['10d'] = 'weather-partly-rainy',
|
||||
['10n'] = 'weather-partly-rainy',
|
||||
['11d'] = 'weather-pouring',
|
||||
['11n'] = 'weather-pouring',
|
||||
['13d'] = 'weather-snowy',
|
||||
['13n'] = 'weather-snowy',
|
||||
['50d'] = 'weather-fog',
|
||||
['50n'] = 'weather-fog',
|
||||
}
|
||||
|
||||
if not instance then
|
||||
instance = setmetatable({}, { __call = function()
|
||||
|
||||
local w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Icon
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
id = 'icon',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(64),
|
||||
height = dpi(64),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{ -- Temperature
|
||||
text = 'NaN°C',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
font = 'JetBrains Mono Bold 24',
|
||||
id = 'temp',
|
||||
},
|
||||
{ -- City, Country
|
||||
text = 'City, Country',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'city_country',
|
||||
},
|
||||
{
|
||||
{ -- Description
|
||||
text = 'NaN',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'description',
|
||||
},
|
||||
fg = Theme_config.notification_center.weather.description_fg,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
{ -- line
|
||||
{
|
||||
bg = Theme_config.notification_center.weather.line_color,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(2),
|
||||
width = dpi(10),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
{ -- Speed
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. 'weather-windy.svg',
|
||||
Theme_config.notification_center.weather.speed_icon_color),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
text = 'NaN m/s',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'speed',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{
|
||||
{ -- Humidity
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = gcolor.recolor_image(icondir .. 'humidity.svg',
|
||||
Theme_config.notification_center.weather.humidity_icon_color),
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
text = 'NaN%',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'humidity',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
border_color = Theme_config.notification_center.weather.border_color,
|
||||
border_width = Theme_config.notification_center.weather.border_width,
|
||||
shape = Theme_config.notification_center.weather.shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
top = dpi(20),
|
||||
left = dpi(20),
|
||||
right = dpi(10),
|
||||
bottom = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(250),
|
||||
strategy = 'exact',
|
||||
}
|
||||
|
||||
gtimer {
|
||||
timeout = 900,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
aspawn.easy_async_with_shell("curl -sf 'http://api.openweathermap.org/data/2.5/weather?id=" ..
|
||||
User_config.weather_secrets.city_id .. '&units=' .. User_config.weather_secrets.unit .. '&appid=' .. User_config.weather_secrets.key .. "'",
|
||||
function(stdout)
|
||||
if not stdout:match('error') then
|
||||
local weather_metadata = json_lua:decode(stdout)
|
||||
if weather_metadata then
|
||||
w:get_children_by_id('icon')[1].image = icondir .. icon_table[weather_metadata.weather[1].icon] .. '.svg'
|
||||
w:get_children_by_id('temp')[1].text = math.floor(weather_metadata.main.temp + 0.5) .. '°C'
|
||||
w:get_children_by_id('city_country')[1].text = weather_metadata.name .. ', ' .. weather_metadata.sys.country
|
||||
w:get_children_by_id('description')[1].text = weather_metadata.weather[1].description:sub(1, 1):upper() ..
|
||||
weather_metadata.weather[1].description:sub(2)
|
||||
w:get_children_by_id('speed')[1].text = weather_metadata.wind.speed .. ' m/s'
|
||||
w:get_children_by_id('humidity')[1].text = weather_metadata.main.humidity .. '%'
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
end,
|
||||
}
|
||||
|
||||
return w
|
||||
|
||||
end, })
|
||||
end
|
||||
|
||||
return instance
|
||||
214
awesome/src/modules/powermenu/init.lua
Normal file
214
awesome/src/modules/powermenu/init.lua
Normal file
@@ -0,0 +1,214 @@
|
||||
--------------------------------
|
||||
-- This is the network widget --
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require('awful.button')
|
||||
local akey = require('awful.key')
|
||||
local akeygrabber = require('awful.keygrabber')
|
||||
local aspawn = require('awful.spawn')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gtable = require('gears.table')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
screen = screen,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/powermenu/'
|
||||
|
||||
local instance = nil
|
||||
local powermenu = {}
|
||||
|
||||
local function get_button(type)
|
||||
local icon, name, bg_color, command
|
||||
|
||||
if type == 'shutdown' then
|
||||
icon = icondir .. 'shutdown.svg'
|
||||
name = 'Shutdown'
|
||||
bg_color = Theme_config.powermenu.shutdown_button_bg
|
||||
command = 'shutdown now'
|
||||
elseif type == 'reboot' then
|
||||
icon = icondir .. 'reboot.svg'
|
||||
name = 'Reboot'
|
||||
bg_color = Theme_config.powermenu.reboot_button_bg
|
||||
command = 'reboot'
|
||||
elseif type == 'logout' then
|
||||
icon = icondir .. 'logout.svg'
|
||||
name = 'Logout'
|
||||
bg_color = Theme_config.powermenu.logout_button_bg
|
||||
command = 'awesome-client "awesome.quit()"'
|
||||
elseif type == 'lock' then
|
||||
icon = icondir .. 'lock.svg'
|
||||
name = 'Lock'
|
||||
bg_color = Theme_config.powermenu.lock_button_bg
|
||||
command = 'dm-tool lock'
|
||||
elseif type == 'suspend' then
|
||||
icon = icondir .. 'suspend.svg'
|
||||
name = 'Suspend'
|
||||
bg_color = Theme_config.powermenu.suspend_button_bg
|
||||
command = 'systemctl suspend'
|
||||
end
|
||||
|
||||
local widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
image = icon,
|
||||
resize = true,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{
|
||||
text = name,
|
||||
font = 'JetBrains Mono Bold 30',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
widget = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
fg = Theme_config.powermenu.button_fg,
|
||||
bg = bg_color,
|
||||
shape = Theme_config.powermenu.button_shape,
|
||||
widget = wibox.container.background,
|
||||
id = 'background',
|
||||
},
|
||||
height = dpi(70),
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
}
|
||||
|
||||
hover.bg_hover { widget = widget.background, overlay = 12, press_overlay = 24 }
|
||||
|
||||
widget:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
aspawn(command)
|
||||
end)
|
||||
))
|
||||
|
||||
return widget
|
||||
end
|
||||
|
||||
function powermenu:toggle()
|
||||
self.keygrabber:start()
|
||||
self.visible = not self.visible
|
||||
end
|
||||
|
||||
function powermenu.new()
|
||||
local w = wibox {
|
||||
widget = {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
image = icondir .. 'defaultpfp.svg',
|
||||
resize = true,
|
||||
clip_shape = Theme_config.powermenu.profile_picture_shape,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(200),
|
||||
height = dpi(200),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
font = 'JetBrains Mono Bold 30',
|
||||
id = 'text_role',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(50),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
{
|
||||
{
|
||||
get_button('shutdown'),
|
||||
get_button('reboot'),
|
||||
get_button('logout'),
|
||||
get_button('lock'),
|
||||
get_button('suspend'),
|
||||
spacing = dpi(30),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
spacing = dpi(50),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
screen = capi.screen.primary,
|
||||
type = 'splash',
|
||||
visible = false,
|
||||
ontop = true,
|
||||
bg = Theme_config.powermenu.container_bg,
|
||||
height = capi.screen.primary.geometry.height,
|
||||
width = capi.screen.primary.geometry.width,
|
||||
x = capi.screen.primary.geometry.x,
|
||||
y = capi.screen.primary.geometry.y,
|
||||
}
|
||||
|
||||
gtable.crush(w, powermenu, true)
|
||||
|
||||
w:buttons { gtable.join(
|
||||
abutton({}, 3, function()
|
||||
w:toggle()
|
||||
w.keygrabber:stop()
|
||||
end)
|
||||
), }
|
||||
|
||||
w.keygrabber = akeygrabber {
|
||||
autostart = false,
|
||||
stop_event = 'release',
|
||||
stop_key = 'Escape',
|
||||
keybindings = {
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Escape',
|
||||
on_press = function()
|
||||
w:toggle()
|
||||
end,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- Get the profile script from /var/lib/AccountsService/icons/${USER}
|
||||
-- and copy it to the assets folder
|
||||
-- TODO: If the user doesnt have AccountsService look into $HOME/.faces
|
||||
aspawn.easy_async_with_shell("./.config/awesome/src/scripts/pfp.sh 'userPfp'", function(stdout)
|
||||
if stdout then
|
||||
w:get_children_by_id('icon_role')[1].image = stdout:gsub('\n', '')
|
||||
else
|
||||
w:get_children_by_id('icon_role')[1].image = icondir .. 'defaultpfp.svg'
|
||||
end
|
||||
end)
|
||||
|
||||
aspawn.easy_async_with_shell("./.config/awesome/src/scripts/pfp.sh 'userName' '" .. User_config.namestyle .. "'", function(stdout)
|
||||
w:get_children_by_id('text_role')[1].text = stdout:gsub('\n', '')
|
||||
end)
|
||||
|
||||
return w
|
||||
end
|
||||
|
||||
if instance == nil then
|
||||
instance = powermenu.new()
|
||||
end
|
||||
return instance
|
||||
@@ -1,249 +0,0 @@
|
||||
--------------------------------
|
||||
-- This is the network widget --
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/powermenu/"
|
||||
|
||||
return function(s)
|
||||
|
||||
-- Profile picture imagebox
|
||||
local profile_picture = wibox.widget {
|
||||
image = icondir .. "defaultpfp.svg",
|
||||
resize = true,
|
||||
forced_height = dpi(200),
|
||||
clip_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(30))
|
||||
end,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
-- Username textbox
|
||||
local profile_name = wibox.widget {
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
text = " ",
|
||||
font = "JetBrains Mono Bold 30",
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
-- Get the profile script from /var/lib/AccountsService/icons/${USER}
|
||||
-- and copy it to the assets folder
|
||||
-- TODO: If the user doesnt have AccountsService look into $HOME/.faces
|
||||
local update_profile_picture = function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"./.config/awesome/src/scripts/pfp.sh 'userPfp'",
|
||||
function(stdout)
|
||||
if stdout then
|
||||
profile_picture:set_image(stdout:gsub("\n", ""))
|
||||
else
|
||||
profile_picture:set_image(icondir .. "defaultpfp.svg")
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
update_profile_picture()
|
||||
|
||||
-- Get the full username(if set) and the username + hostname
|
||||
local update_user_name = function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"./.config/awesome/src/scripts/pfp.sh 'userName' '" .. User_config.namestyle .. "'",
|
||||
function(stdout)
|
||||
if stdout:gsub("\n", "") == "Rick Astley" then
|
||||
profile_picture:set_image(gears.filesystem.get_configuration_dir() .. "src/assets/userpfp/" .. "rickastley.jpg")
|
||||
end
|
||||
profile_name:set_text(stdout)
|
||||
end
|
||||
)
|
||||
end
|
||||
update_user_name()
|
||||
|
||||
-- Universal Button widget
|
||||
local button = function(name, icon, bg_color, callback)
|
||||
local item = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
-- TODO: using gears.color to recolor a SVG will make it look super low res
|
||||
-- currently I recolor it in the .svg file directly, but later implement
|
||||
-- a better way to recolor a SVG
|
||||
image = icon,
|
||||
resize = true,
|
||||
forced_height = dpi(30),
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{
|
||||
text = name,
|
||||
font = "JetBrains Mono Bold 30",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
widget = wibox.layout.fixed.horizontal
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
fg = Theme_config.powermenu.button_fg,
|
||||
bg = bg_color,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(10))
|
||||
end,
|
||||
widget = wibox.container.background,
|
||||
id = 'background'
|
||||
},
|
||||
layout = wibox.layout.align.vertical
|
||||
}
|
||||
|
||||
item:connect_signal(
|
||||
"button::release",
|
||||
function()
|
||||
callback()
|
||||
end
|
||||
)
|
||||
|
||||
return item
|
||||
end
|
||||
|
||||
-- Create the power menu actions
|
||||
local suspend_command = function()
|
||||
awful.spawn("systemctl suspend")
|
||||
capi.awesome.emit_signal("module::powermenu:hide")
|
||||
end
|
||||
|
||||
local logout_command = function()
|
||||
capi.awesome.quit()
|
||||
end
|
||||
|
||||
local lock_command = function()
|
||||
awful.spawn("dm-tool lock")
|
||||
capi.awesome.emit_signal("module::powermenu:hide")
|
||||
end
|
||||
|
||||
local shutdown_command = function()
|
||||
awful.spawn("shutdown now")
|
||||
capi.awesome.emit_signal("module::powermenu:hide")
|
||||
end
|
||||
|
||||
local reboot_command = function()
|
||||
awful.spawn("reboot")
|
||||
capi.awesome.emit_signal("module::powermenu:hide")
|
||||
end
|
||||
|
||||
-- Create the buttons with their command and name etc
|
||||
local shutdown_button = button("Shutdown", icondir .. "shutdown.svg", Theme_config.powermenu.shutdown_button_bg,
|
||||
shutdown_command)
|
||||
local reboot_button = button("Reboot", icondir .. "reboot.svg", Theme_config.powermenu.reboot_button_bg, reboot_command)
|
||||
local suspend_button = button("Suspend", icondir .. "suspend.svg", Theme_config.powermenu.suspend_button_bg,
|
||||
suspend_command)
|
||||
local logout_button = button("Logout", icondir .. "logout.svg", Theme_config.powermenu.logout_button_bg, logout_command)
|
||||
local lock_button = button("Lock", icondir .. "lock.svg", Theme_config.powermenu.lock_button_bg, lock_command)
|
||||
|
||||
-- Signals to change color on hover
|
||||
Hover_signal(shutdown_button.background)
|
||||
Hover_signal(reboot_button.background)
|
||||
Hover_signal(suspend_button.background)
|
||||
Hover_signal(logout_button.background)
|
||||
Hover_signal(lock_button.background)
|
||||
|
||||
-- The powermenu widget
|
||||
local powermenu = wibox.widget {
|
||||
{
|
||||
{
|
||||
profile_picture,
|
||||
profile_name,
|
||||
spacing = dpi(50),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
{
|
||||
{
|
||||
shutdown_button,
|
||||
reboot_button,
|
||||
logout_button,
|
||||
lock_button,
|
||||
suspend_button,
|
||||
spacing = dpi(30),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
}
|
||||
|
||||
-- Container for the widget, covers the entire screen
|
||||
local powermenu_container = wibox {
|
||||
widget = powermenu,
|
||||
screen = s,
|
||||
type = "splash",
|
||||
visible = false,
|
||||
ontop = true,
|
||||
bg = Theme_config.powermenu.container_bg,
|
||||
height = s.geometry.height,
|
||||
width = s.geometry.width,
|
||||
x = s.geometry.x,
|
||||
y = s.geometry.y
|
||||
}
|
||||
|
||||
-- Close on rightclick
|
||||
powermenu_container:buttons(
|
||||
gears.table.join(
|
||||
awful.button(
|
||||
{},
|
||||
3,
|
||||
function()
|
||||
capi.awesome.emit_signal("module::powermenu:hide")
|
||||
end
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
-- Close on Escape
|
||||
local powermenu_keygrabber = awful.keygrabber {
|
||||
autostart = false,
|
||||
stop_event = 'release',
|
||||
keypressed_callback = function(self, mod, key, command)
|
||||
if key == 'Escape' then
|
||||
capi.awesome.emit_signal("module::powermenu:hide")
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
-- Signals
|
||||
capi.awesome.connect_signal(
|
||||
"module::powermenu:show",
|
||||
function()
|
||||
if s == capi.mouse.screen then
|
||||
powermenu_container.visible = true
|
||||
powermenu_keygrabber:start()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"module::powermenu:hide",
|
||||
function()
|
||||
powermenu_keygrabber:stop()
|
||||
powermenu_container.visible = false
|
||||
end
|
||||
)
|
||||
end
|
||||
@@ -3,13 +3,13 @@
|
||||
---------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gears = require('gears')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local color = require("src.lib.color")
|
||||
local rubato = require("src.lib.rubato")
|
||||
local color = require('src.lib.color')
|
||||
local rubato = require('src.lib.rubato')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
@@ -21,13 +21,13 @@ return function()
|
||||
local elements = wibox.widget {
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
spacing = dpi(20),
|
||||
id = "switcher"
|
||||
id = 'switcher',
|
||||
}
|
||||
|
||||
local selected = 0
|
||||
|
||||
local function create_elements(fn)
|
||||
fn = fn or ""
|
||||
fn = fn or ''
|
||||
|
||||
elements:reset()
|
||||
|
||||
@@ -53,44 +53,43 @@ return function()
|
||||
{
|
||||
{ -- Icon
|
||||
{
|
||||
id = "icon",
|
||||
id = 'icon',
|
||||
--!ADD FALLBACK ICON!--
|
||||
image = Get_icon(client.class, client.name) or client.icon,
|
||||
--image = gears.surface(client.content),
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
image = gears.surface(client.icon),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
width = dpi(100),
|
||||
height = dpi(100),
|
||||
id = "icon_const",
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
id = 'icon_const',
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
{
|
||||
text = client.name,
|
||||
id = "label",
|
||||
widget = wibox.widget.textbox
|
||||
id = 'label',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
id = "place",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place
|
||||
id = 'place',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
id = "layout1",
|
||||
id = 'layout1',
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
id = "box",
|
||||
id = 'box',
|
||||
width = dpi(150),
|
||||
height = dpi(150),
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
id = "margin",
|
||||
id = 'margin',
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(12))
|
||||
@@ -99,13 +98,13 @@ return function()
|
||||
border_width = Theme_config.window_switcher.border_width,
|
||||
bg = Theme_config.window_switcher.bg,
|
||||
fg = Theme_config.window_switcher.element_fg,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
elements:add(window_element)
|
||||
end
|
||||
|
||||
if fn == "next" then
|
||||
if fn == 'next' then
|
||||
if selected >= #clients_sorted then
|
||||
selected = 1
|
||||
else
|
||||
@@ -153,15 +152,15 @@ return function()
|
||||
end
|
||||
|
||||
local function update_bg()
|
||||
element:set_bg("#" .. color.utils.rgba_to_hex { r_timed_bg.pos, g_timed_bg.pos, b_timed_bg.pos })
|
||||
element:set_bg('#' .. color.utils.rgba_to_hex { r_timed_bg.pos, g_timed_bg.pos, b_timed_bg.pos })
|
||||
end
|
||||
|
||||
local function update_fg()
|
||||
element:set_fg("#" .. color.utils.rgba_to_hex { r_timed_fg.pos, g_timed_fg.pos, b_timed_fg.pos })
|
||||
element:set_fg('#' .. color.utils.rgba_to_hex { r_timed_fg.pos, g_timed_fg.pos, b_timed_fg.pos })
|
||||
end
|
||||
|
||||
local function update_border()
|
||||
element.border_color = "#" ..
|
||||
element.border_color = '#' ..
|
||||
color.utils.rgba_to_hex { r_timed_border.pos, g_timed_border.pos, b_timed_border.pos }
|
||||
end
|
||||
|
||||
@@ -202,7 +201,7 @@ return function()
|
||||
set_bg(Theme_config.window_switcher.bg)
|
||||
end
|
||||
end
|
||||
elseif fn == "raise" then
|
||||
elseif fn == 'raise' then
|
||||
local c = clients_sorted[selected]
|
||||
if not c:isvisible() and c.first_tag then
|
||||
c.first_tag:view_only()
|
||||
@@ -219,35 +218,35 @@ return function()
|
||||
elements = create_elements()
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"window_switcher::select_next",
|
||||
'window_switcher::select_next',
|
||||
function()
|
||||
elements = create_elements("next")
|
||||
elements = create_elements('next')
|
||||
end
|
||||
)
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"window_switcher::raise",
|
||||
'window_switcher::raise',
|
||||
function()
|
||||
elements = create_elements("raise")
|
||||
elements = create_elements('raise')
|
||||
end
|
||||
)
|
||||
|
||||
capi.client.connect_signal(
|
||||
"manage",
|
||||
'manage',
|
||||
function()
|
||||
elements = create_elements()
|
||||
end
|
||||
)
|
||||
|
||||
capi.client.connect_signal(
|
||||
"unmanage",
|
||||
'unmanage',
|
||||
function()
|
||||
elements = create_elements()
|
||||
end
|
||||
)
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"window_switcher::update",
|
||||
'window_switcher::update',
|
||||
function()
|
||||
elements = create_elements()
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user