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