Reworked a whole lot. New config file and theme config file for easier changes. Did #19. And much more

This commit is contained in:
Kievits Rene
2022-06-14 06:33:33 +02:00
parent fd74ab9fb4
commit 521d392769
60 changed files with 2216 additions and 1450 deletions

View File

@@ -0,0 +1,236 @@
-----------------------------------------------------
-- Helper to get icons from a program/program name --
-----------------------------------------------------
local gears = require("gears")
local GLib = require("lgi").GLib
local theme_index = require("src.tools.theme_index")
local function get_basedir()
local dirs = {}
local dir = GLib.build_filenamev({ GLib.get_home_dir(), ".icons" })
if gears.filesystem.dir_readable(dir) then
table.insert(dirs, dir)
end
dir = GLib.build_filenamev({ GLib.get_user_data_dir(), "icons" })
if gears.filesystem.dir_readable(dir) then table.insert(dirs, dir) end
for _, value in ipairs(GLib.get_system_data_dirs()) do
dir = GLib.build_filenamev({ value, ".icons" })
if gears.filesystem.dir_readable(dir) then table.insert(dirs, dir) end
end
local need_usr_share_pixmaps = true
for _, value in ipairs(GLib.get_system_data_dirs()) do
dir = GLib.build_filenamev({ value, ".icons" })
if gears.filesystem.dir_readable(dir) then table.insert(dirs, dir) end
if dir == "/usr/share/pixmaps" then
need_usr_share_pixmaps = false
end
end
dir = "/usr/share/pixmaps"
if gears.filesystem.dir_readable(dir) then table.insert(dirs, dir) end
if need_usr_share_pixmaps and gears.filesystem.dir_readable(dir) then
table.insert(dirs, dir)
end
table.insert(dirs, "/usr/share/icons")
return dirs
end
local xdg_icon_lookup = { mt = {} }
local icon_cache = {}
xdg_icon_lookup.new = function(theme, base_dirs)
local self = {}
self.icon_theme = theme or User_config.icon_theme
self.base_directories = base_dirs or get_basedir()
self.file_extension = { "svg", "png", "xpm" }
if not icon_cache[self.icon_theme] then
icon_cache[self.icon_theme] = {}
end
local cache_key = table.concat(self.base_directories, ":")
if not icon_cache[self.icon_theme][cache_key] then
icon_cache[self.icon_theme][cache_key] = theme_index(self.icon_theme, self.base_directories)
end
self.theme_index = icon_cache[self.icon_theme][cache_key]
return setmetatable(self, { __index = xdg_icon_lookup })
end
---Look for an fallback icon
---@param iconname any
---@return string
local function lookup_fallback_icon(self, iconname)
for _, dir in ipairs(self.base_directories) do
for _, ext in ipairs(self.file_extension) do
local filename = string.format("%s/%s.%s", dir, iconname, ext)
if gears.filesystem.file_readable(filename) then
return filename
end
end
end
end
---Checkes if the size equals the actual icon size
---@param subdir any
---@param iconsize any
---@return boolean
local function directory_matches_size(self, subdir, iconsize)
local type, size, min_size, max_size, threshold = self.theme_index.per_directory_keys[subdir]["Type"],
self.theme_index.per_directory_keys[subdir]["Size"], self.theme_index.per_directory_keys[subdir]["MinSize"],
self.theme_index.per_directory_keys[subdir]["MaxSize"], self.theme_index.per_directory_keys[subdir]["Threshold"]
if type == "Fixed" then
return iconsize == size
elseif type == "Scalable" then
return iconsize >= min_size and iconsize <= max_size
elseif type == "Threshold" then
return iconsize >= size - threshold and iconsize <= size + threshold
end
return false
end
---Returns how far off the size is from the actual icon size
---@param subdir table
---@param iconsize number
---@return number
local function directory_size_distance(self, subdir, iconsize)
local type, size, min_size, max_size, threshold = self.theme_index.per_directory_keys[subdir]["Type"],
self.theme_index.per_directory_keys[subdir]["Size"], self.theme_index.per_directory_keys[subdir]["MinSize"],
self.theme_index.per_directory_keys[subdir]["MaxSize"], self.theme_index.per_directory_keys[subdir]["Threshold"]
if type and min_size and max_size and threshold then
if type == "Fixed" then
return math.abs(size - iconsize)
elseif type == "Scalable" then
if iconsize < min_size then
return min_size - iconsize
elseif iconsize > max_size then
return iconsize - max_size
end
return 0
elseif type == "Threshold" then
if iconsize < size - threshold then
return min_size - iconsize
elseif iconsize > size + threshold then
return iconsize - max_size
end
return 0
end
end
return 0xffffffff
end
---Checks each and every sub directory for an icon
---@param iconname any
---@param size any
---@return string path_to_icon
local function lookup_icon(self, iconname, size)
local already_checked = {}
for _, subdir in ipairs(self.theme_index:get_subdirectories()) do
for _, dir in ipairs(self.base_directories) do
for _, ext in ipairs(self.file_extension) do
if directory_matches_size(self, subdir, size) then
local filename = string.format("%s/%s/%s/%s.%s", dir, self.icon_theme, subdir, iconname, ext)
if gears.filesystem.file_readable(filename) then
return filename
else
already_checked[filename] = true
end
end
end
end
end
local min_size = 0xffffffff
local closest_filename = nil
for _, subdir in ipairs(self.theme_index:get_subdirectories()) do
local dist = directory_size_distance(self, subdir, size)
if dist < min_size then
for _, dir in ipairs(self.base_directories) do
for _, ext in ipairs(self.file_extension) do
local filename = string.format("%s/%s/%s/%s.%s", dir, self.icon_theme, subdir, iconname, ext)
if not already_checked[filename] then
if gears.filesystem.file_readable(filename) then
closest_filename = filename
min_size = dist
end
end
end
end
end
end
return closest_filename or nil
end
---Check if the icon inherits from another icon theme and search that for an icon
---@param icon any
---@param size any
---@param self any
---@return string path_to_icon
local function find_icon_helper(self, icon, size)
local filename = lookup_icon(self, icon, size)
if filename then return filename end
filename = lookup_icon(self, icon:lower(), size)
if filename then return filename end
for _, parent in ipairs(self.theme_index:get_inherits()) do
filename = find_icon_helper(xdg_icon_lookup(parent, self.base_directories), icon, size)
if filename then return filename end
end
return nil
end
local iconcache = {}
---Takes an icon and its props and theme to search for it inside the theme
---@param icon any
---@param size any
---@return string path_to_icon
function xdg_icon_lookup:find_icon(icon, size)
if iconcache[icon] then
return iconcache[icon]
end
size = size or 64
if not icon or icon == "" then return nil end
local filename = find_icon_helper(self, icon, size)
if filename then
iconcache[icon] = filename
return filename
end
filename = find_icon_helper(xdg_icon_lookup("hicolor", self.base_directories), icon, size)
if filename then
iconcache[icon] = filename
return filename
end
filename = lookup_fallback_icon(self, icon)
if filename then
iconcache[icon] = filename
return filename
end
local fallback = gears.color.recolor_image(require("awful").util.getdir("config") .. "src/assets/icons/fallback.svg",
"#ffffff")
iconcache[icon] = fallback
return fallback
end
xdg_icon_lookup.mt.__call = function(_, ...)
return xdg_icon_lookup.new(...)
end
return setmetatable(xdg_icon_lookup, xdg_icon_lookup.mt)