svg.rs

 1use crate::{
 2    self as gpui2, scene,
 3    style::{Style, StyleHelpers, Styleable},
 4    Element, IntoElement, Layout, LayoutId, Rgba,
 5};
 6use refineable::RefinementCascade;
 7use std::borrow::Cow;
 8use util::ResultExt;
 9
10#[derive(IntoElement)]
11pub struct Svg {
12    path: Option<Cow<'static, str>>,
13    style: RefinementCascade<Style>,
14}
15
16pub fn svg() -> Svg {
17    Svg {
18        path: None,
19        style: RefinementCascade::<Style>::default(),
20    }
21}
22
23impl Svg {
24    pub fn path(mut self, path: impl Into<Cow<'static, str>>) -> Self {
25        self.path = Some(path.into());
26        self
27    }
28}
29
30impl<V: 'static> Element<V> for Svg {
31    type PaintState = ();
32
33    fn layout(
34        &mut self,
35        _: &mut V,
36        cx: &mut crate::LayoutContext<V>,
37    ) -> anyhow::Result<(LayoutId, Self::PaintState)>
38    where
39        Self: Sized,
40    {
41        let style = self.computed_style();
42        Ok((cx.add_layout_node(style, [])?, ()))
43    }
44
45    fn paint(
46        &mut self,
47        _: &mut V,
48        layout: &Layout,
49        _: &mut Self::PaintState,
50        cx: &mut crate::paint_context::PaintContext<V>,
51    ) where
52        Self: Sized,
53    {
54        let fill_color = self.computed_style().fill.and_then(|fill| fill.color());
55        if let Some((path, fill_color)) = self.path.as_ref().zip(fill_color) {
56            if let Some(svg_tree) = cx.asset_cache.svg(path).log_err() {
57                let icon = scene::Icon {
58                    bounds: layout.bounds,
59                    svg: svg_tree,
60                    path: path.clone(),
61                    color: Rgba::from(fill_color).into(),
62                };
63
64                cx.scene.push_icon(icon);
65            }
66        }
67    }
68}
69
70impl Styleable for Svg {
71    type Style = Style;
72
73    fn style_cascade(&mut self) -> &mut refineable::RefinementCascade<Self::Style> {
74        &mut self.style
75    }
76
77    fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
78        self.style.base()
79    }
80}
81
82impl StyleHelpers for Svg {}