yes, I'm very commit lazy

This commit is contained in:
2023-03-19 19:22:02 +01:00
parent 4f3fb75687
commit f399235db0
107 changed files with 11120 additions and 10906 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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()