svg.rs

 1use crate::{
 2    AnyElement, Bounds, Element, IntoAnyElement, LayoutId, Pixels, SharedString, Style, Styled,
 3};
 4use refineable::Cascade;
 5use std::marker::PhantomData;
 6use util::ResultExt;
 7
 8pub struct Svg<S> {
 9    path: Option<SharedString>,
10    style: Cascade<Style>,
11    state_type: PhantomData<S>,
12}
13
14pub fn svg<S>() -> Svg<S> {
15    Svg {
16        path: None,
17        style: Cascade::<Style>::default(),
18        state_type: PhantomData,
19    }
20}
21
22impl<S> Svg<S> {
23    pub fn path(mut self, path: impl Into<SharedString>) -> Self {
24        self.path = Some(path.into());
25        self
26    }
27}
28
29impl<S> IntoAnyElement<S> for Svg<S>
30where
31    S: 'static + Send + Sync,
32{
33    fn into_any(self) -> AnyElement<S> {
34        AnyElement::new(self)
35    }
36}
37
38impl<S: 'static + Send + Sync> Element for Svg<S> {
39    type ViewState = S;
40    type ElementState = ();
41
42    fn element_id(&self) -> Option<crate::ElementId> {
43        None
44    }
45
46    fn layout(
47        &mut self,
48        _: &mut S,
49        _: Option<Self::ElementState>,
50        cx: &mut crate::ViewContext<S>,
51    ) -> (LayoutId, Self::ElementState)
52    where
53        Self: Sized,
54    {
55        let style = self.computed_style();
56        (cx.request_layout(style, []), ())
57    }
58
59    fn paint(
60        &mut self,
61        bounds: Bounds<Pixels>,
62        _: &mut Self::ViewState,
63        _: &mut Self::ElementState,
64        cx: &mut crate::ViewContext<S>,
65    ) where
66        Self: Sized,
67    {
68        let fill_color = self.computed_style().fill.and_then(|fill| fill.color());
69        if let Some((path, fill_color)) = self.path.as_ref().zip(fill_color) {
70            cx.paint_svg(bounds, path.clone(), fill_color).log_err();
71        }
72    }
73}
74
75impl<S: 'static + Send + Sync> Styled for Svg<S> {
76    type Style = Style;
77
78    fn style_cascade(&mut self) -> &mut refineable::Cascade<Self::Style> {
79        &mut self.style
80    }
81
82    fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
83        self.style.base()
84    }
85}