fix: merge themes from multiple locations
This commit is contained in:
parent
1be7d4e73b
commit
92f759fd09
4 changed files with 51 additions and 22 deletions
27
src/lib.rs
27
src/lib.rs
|
|
@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
));
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue