From 38f7af6c07e851b9f7d470e3ca2611475c57cb3c Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Fri, 16 Dec 2022 17:10:22 -0500 Subject: [PATCH] refactor: allow the icon to be non-svg --- src/widget/icon.rs | 81 +++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/src/widget/icon.rs b/src/widget/icon.rs index 0d5311c1..bccf63cf 100644 --- a/src/widget/icon.rs +++ b/src/widget/icon.rs @@ -7,13 +7,13 @@ use iced::{ widget::{svg, Image}, Length, ContentFit, }; -use std::borrow::Cow; +use std::{borrow::Cow, ffi::OsStr}; use std::hash::Hash; use std::rc::Rc; use derive_setters::Setters; use crate::{Element, Renderer}; -/// A lazily-generated SVG icon. +/// A lazily-generated icon. #[derive(Hash, Setters)] pub struct Icon<'a> { #[setters(skip)] @@ -30,18 +30,7 @@ pub struct Icon<'a> { height: Option, } -pub fn image_icon(name: &str, size: u16) -> Option { - freedesktop_icons::lookup(name) - .with_size(size) - .with_cache() - .find() - .map(|path| { - Image::new(path) - .width(Length::Units(size)) - .height(Length::Units(size)) - }) -} -/// A lazily-generated SVG icon. +/// A lazily-generated icon. #[must_use] pub fn icon<'a>(name: impl Into>, size: u16) -> Icon<'a> { Icon { @@ -57,41 +46,59 @@ pub fn icon<'a>(name: impl Into>, size: u16) -> Icon<'a> { impl<'a> Icon<'a> { #[must_use] - fn into_svg(self) -> Element<'a, Message> { - let svg = Rc::new(self); - let svg_clone = Rc::clone(&svg); + fn into_element(self) -> Element<'a, Message> { + let element = Rc::new(self); + let element_clone = Rc::clone(&element); - iced_lazy::lazy(svg_clone, move || -> Element { - let icon = freedesktop_icons::lookup(&svg.name) - .with_size(svg.size) - .with_theme(&svg.theme) + iced_lazy::lazy(element_clone, move || -> Element { + let icon = freedesktop_icons::lookup(&element.name) + .with_size(element.size) + .with_theme(&element.theme) .with_cache() - .force_svg() .find(); - - let handle = if let Some(path) = icon { - svg::Handle::from_path(path) + let icon = if icon.is_none() { + freedesktop_icons::lookup(&element.name) + .with_size(element.size) + .with_cache() + .find() } else { - eprintln!("icon '{}' size {} not found", svg.name, svg.size); - svg::Handle::from_memory(Vec::new()) + icon }; - let mut widget = svg::Svg::::new(handle) - .style(svg.style) - .width(svg.width.unwrap_or(Length::Units(svg.size))) - .height(svg.height.unwrap_or(Length::Units(svg.size))); - - if let Some(content_fit) = svg.content_fit { - widget = widget.content_fit(content_fit); + if icon.as_ref().map(|path| path.extension() == Some(&OsStr::new("svg"))).unwrap_or(true) { + let handle = if let Some(path) = icon { + svg::Handle::from_path(path) + } else { + eprintln!("icon '{}' size {} not found", element.name, element.size); + svg::Handle::from_memory(Vec::new()) + }; + + let mut widget = svg::Svg::::new(handle) + .style(element.style) + .width(element.width.unwrap_or(Length::Units(element.size))) + .height(element.height.unwrap_or(Length::Units(element.size))); + + if let Some(content_fit) = element.content_fit { + widget = widget.content_fit(content_fit); + } + + widget.into() + } else { + let icon_path = icon.unwrap(); + let mut image = Image::new(icon_path) + .width(element.width.unwrap_or(Length::Units(element.size))) + .height(element.height.unwrap_or(Length::Units(element.size))); + if let Some(content_fit) = element.content_fit { + image = image.content_fit(content_fit); + } + image.into() } - - widget.into() }).into() } } impl<'a, Message: 'static> From> for Element<'a, Message> { fn from(icon: Icon<'a>) -> Self { - icon.into_svg::() + icon.into_element::() } }