fix: merge themes from multiple locations

This commit is contained in:
Victoria Brekenfeld 2023-01-09 23:54:07 +01:00 committed by Paul Delafosse
parent 1be7d4e73b
commit 92f759fd09
4 changed files with 51 additions and 22 deletions

View file

@ -75,15 +75,18 @@ mod theme;
/// ])
/// # }
pub fn list_themes() -> Vec<&'static str> {
THEMES
let mut themes = THEMES
.values()
.flatten()
.map(|path| &path.index)
.filter_map(|index| {
index
.section(Some("Icon Theme"))
.and_then(|section| section.get("Name"))
})
.collect()
.collect::<Vec<_>>();
themes.dedup();
themes
}
/// The lookup builder struct, holding all the lookup query parameters.
@ -232,14 +235,24 @@ impl<'a> LookupBuilder<'a> {
}
// Then lookup in the given theme
THEMES.get(self.theme).and_then(|icon_theme| {
let icon = icon_theme
.try_get_icon(self.name, self.size, self.scale, self.force_svg)
THEMES.get(self.theme).and_then(|icon_themes| {
let icon = icon_themes
.iter()
.find_map(|theme| {
theme.try_get_icon(self.name, self.size, self.scale, self.force_svg)
})
.or_else(|| {
// Fallback to the parent themes recursively
icon_theme.inherits().into_iter().find_map(|parent| {
let mut parents = icon_themes
.iter()
.flat_map(|t| t.inherits())
.collect::<Vec<_>>();
parents.dedup();
parents.into_iter().find_map(|parent| {
THEMES.get(parent).and_then(|parent| {
parent.try_get_icon(self.name, self.size, self.scale, self.force_svg)
parent.iter().find_map(|t| {
t.try_get_icon(self.name, self.size, self.scale, self.force_svg)
})
})
})
})

View file

@ -14,7 +14,7 @@ mod paths;
type Result<T> = std::result::Result<T, ThemeError>;
pub static THEMES: Lazy<BTreeMap<String, Theme>> =
pub static THEMES: Lazy<BTreeMap<String, Vec<Theme>>> =
Lazy::new(|| get_all_themes().expect("Failed to get theme paths"));
pub struct Theme {
@ -140,14 +140,14 @@ fn try_build_xmp<P: AsRef<Path>>(name: &str, path: P) -> Option<PathBuf> {
}
// Iter through the base paths and get all theme directories
pub(super) fn get_all_themes() -> Result<BTreeMap<String, Theme>> {
let mut icon_themes = BTreeMap::new();
pub(super) fn get_all_themes() -> Result<BTreeMap<String, Vec<Theme>>> {
let mut icon_themes = BTreeMap::<_, Vec<_>>::new();
for theme_base_dir in BASE_PATHS.iter() {
for entry in theme_base_dir.read_dir()? {
let entry = entry?;
if let Some(theme) = Theme::from_path(entry.path()) {
let name = entry.file_name().to_string_lossy().to_string();
icon_themes.insert(name, theme);
icon_themes.entry(name).or_default().push(theme);
}
}
}
@ -190,17 +190,24 @@ mod test {
#[test]
fn get_one_icon() {
let theme = THEMES.get("Adwaita").unwrap();
let themes = THEMES.get("Adwaita").unwrap();
println!(
"{:?}",
theme.try_get_icon_exact_size("edit-delete-symbolic", 24, 1, false)
themes.iter().find_map(|t| t.try_get_icon_exact_size(
"edit-delete-symbolic",
24,
1,
false
))
);
}
#[test]
fn should_get_png_first() {
let theme = THEMES.get("hicolor").unwrap();
let icon = theme.try_get_icon_exact_size("blueman", 24, 1, true);
let themes = THEMES.get("hicolor").unwrap();
let icon = themes
.iter()
.find_map(|t| t.try_get_icon_exact_size("blueman", 24, 1, true));
assert_that!(icon).is_some().is_equal_to(PathBuf::from(
"/usr/share/icons/hicolor/scalable/apps/blueman.svg",
));
@ -208,8 +215,10 @@ mod test {
#[test]
fn should_get_svg_first() {
let theme = THEMES.get("hicolor").unwrap();
let icon = theme.try_get_icon_exact_size("blueman", 24, 1, false);
let themes = THEMES.get("hicolor").unwrap();
let icon = themes
.iter()
.find_map(|t| t.try_get_icon_exact_size("blueman", 24, 1, false));
assert_that!(icon).is_some().is_equal_to(PathBuf::from(
"/usr/share/icons/hicolor/22x22/apps/blueman.png",
));

View file

@ -88,11 +88,18 @@ mod test {
#[test]
fn should_get_theme_parents() {
let theme = THEMES.get("Arc").unwrap();
let parents = theme.inherits();
for theme in THEMES.get("Arc").unwrap() {
let parents = theme.inherits();
assert_that!(parents).does_not_contain("hicolor");
assert_that!(parents).does_not_contain("hicolor");
assert_that!(parents).is_equal_to(vec!["Moka", "Faba", "elementary", "Adwaita", "gnome"]);
assert_that!(parents).is_equal_to(vec![
"Moka",
"Faba",
"elementary",
"Adwaita",
"gnome",
]);
}
}
}

View file

@ -61,7 +61,7 @@ mod test {
#[test]
fn should_read_theme_index() -> Result<()> {
let themes = get_all_themes()?;
let themes: Vec<&Theme> = themes.values().collect();
let themes: Vec<&Theme> = themes.values().flatten().collect();
assert_that!(themes).is_not_empty();
Ok(())
}