refactor: allow the icon to be non-svg
This commit is contained in:
parent
c2625ef450
commit
38f7af6c07
1 changed files with 44 additions and 37 deletions
|
|
@ -7,13 +7,13 @@ use iced::{
|
||||||
widget::{svg, Image},
|
widget::{svg, Image},
|
||||||
Length, ContentFit,
|
Length, ContentFit,
|
||||||
};
|
};
|
||||||
use std::borrow::Cow;
|
use std::{borrow::Cow, ffi::OsStr};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use derive_setters::Setters;
|
use derive_setters::Setters;
|
||||||
use crate::{Element, Renderer};
|
use crate::{Element, Renderer};
|
||||||
|
|
||||||
/// A lazily-generated SVG icon.
|
/// A lazily-generated icon.
|
||||||
#[derive(Hash, Setters)]
|
#[derive(Hash, Setters)]
|
||||||
pub struct Icon<'a> {
|
pub struct Icon<'a> {
|
||||||
#[setters(skip)]
|
#[setters(skip)]
|
||||||
|
|
@ -30,18 +30,7 @@ pub struct Icon<'a> {
|
||||||
height: Option<Length>,
|
height: Option<Length>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn image_icon(name: &str, size: u16) -> Option<Image> {
|
/// A lazily-generated icon.
|
||||||
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.
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn icon<'a>(name: impl Into<Cow<'a, str>>, size: u16) -> Icon<'a> {
|
pub fn icon<'a>(name: impl Into<Cow<'a, str>>, size: u16) -> Icon<'a> {
|
||||||
Icon {
|
Icon {
|
||||||
|
|
@ -57,41 +46,59 @@ pub fn icon<'a>(name: impl Into<Cow<'a, str>>, size: u16) -> Icon<'a> {
|
||||||
|
|
||||||
impl<'a> Icon<'a> {
|
impl<'a> Icon<'a> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn into_svg<Message: 'static>(self) -> Element<'a, Message> {
|
fn into_element<Message: 'static>(self) -> Element<'a, Message> {
|
||||||
let svg = Rc::new(self);
|
let element = Rc::new(self);
|
||||||
let svg_clone = Rc::clone(&svg);
|
let element_clone = Rc::clone(&element);
|
||||||
|
|
||||||
iced_lazy::lazy(svg_clone, move || -> Element<Message> {
|
iced_lazy::lazy(element_clone, move || -> Element<Message> {
|
||||||
let icon = freedesktop_icons::lookup(&svg.name)
|
let icon = freedesktop_icons::lookup(&element.name)
|
||||||
.with_size(svg.size)
|
.with_size(element.size)
|
||||||
.with_theme(&svg.theme)
|
.with_theme(&element.theme)
|
||||||
.with_cache()
|
.with_cache()
|
||||||
.force_svg()
|
|
||||||
.find();
|
.find();
|
||||||
|
let icon = if icon.is_none() {
|
||||||
let handle = if let Some(path) = icon {
|
freedesktop_icons::lookup(&element.name)
|
||||||
svg::Handle::from_path(path)
|
.with_size(element.size)
|
||||||
|
.with_cache()
|
||||||
|
.find()
|
||||||
} else {
|
} else {
|
||||||
eprintln!("icon '{}' size {} not found", svg.name, svg.size);
|
icon
|
||||||
svg::Handle::from_memory(Vec::new())
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut widget = svg::Svg::<Renderer>::new(handle)
|
if icon.as_ref().map(|path| path.extension() == Some(&OsStr::new("svg"))).unwrap_or(true) {
|
||||||
.style(svg.style)
|
let handle = if let Some(path) = icon {
|
||||||
.width(svg.width.unwrap_or(Length::Units(svg.size)))
|
svg::Handle::from_path(path)
|
||||||
.height(svg.height.unwrap_or(Length::Units(svg.size)));
|
} else {
|
||||||
|
eprintln!("icon '{}' size {} not found", element.name, element.size);
|
||||||
if let Some(content_fit) = svg.content_fit {
|
svg::Handle::from_memory(Vec::new())
|
||||||
widget = widget.content_fit(content_fit);
|
};
|
||||||
|
|
||||||
|
let mut widget = svg::Svg::<Renderer>::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()
|
}).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message: 'static> From<Icon<'a>> for Element<'a, Message> {
|
impl<'a, Message: 'static> From<Icon<'a>> for Element<'a, Message> {
|
||||||
fn from(icon: Icon<'a>) -> Self {
|
fn from(icon: Icon<'a>) -> Self {
|
||||||
icon.into_svg::<Message>()
|
icon.into_element::<Message>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue