1use crate::{
2 Bounds, Element, ElementId, InteractiveElement, InteractiveElementState, Interactivity,
3 LayoutId, Pixels, RenderOnce, SharedString, StyleRefinement, Styled, ViewContext,
4};
5use util::ResultExt;
6
7pub struct Svg<V: 'static> {
8 interactivity: Interactivity<V>,
9 path: Option<SharedString>,
10}
11
12pub fn svg<V: 'static>() -> Svg<V> {
13 Svg {
14 interactivity: Interactivity::default(),
15 path: None,
16 }
17}
18
19impl<V> Svg<V> {
20 pub fn path(mut self, path: impl Into<SharedString>) -> Self {
21 self.path = Some(path.into());
22 self
23 }
24}
25
26impl<V> Element<V> for Svg<V> {
27 type State = InteractiveElementState;
28
29 fn layout(
30 &mut self,
31 _view_state: &mut V,
32 element_state: Option<Self::State>,
33 cx: &mut ViewContext<V>,
34 ) -> (LayoutId, Self::State) {
35 self.interactivity.layout(element_state, cx, |style, cx| {
36 cx.request_layout(&style, None)
37 })
38 }
39
40 fn paint(
41 self,
42 bounds: Bounds<Pixels>,
43 _view_state: &mut V,
44 element_state: &mut Self::State,
45 cx: &mut ViewContext<V>,
46 ) where
47 Self: Sized,
48 {
49 self.interactivity
50 .paint(bounds, bounds.size, element_state, cx, |style, _, cx| {
51 if let Some((path, color)) = self.path.as_ref().zip(style.text.color) {
52 cx.paint_svg(bounds, path.clone(), color).log_err();
53 }
54 })
55 }
56}
57
58impl<V: 'static> RenderOnce<V> for Svg<V> {
59 type Element = Self;
60
61 fn element_id(&self) -> Option<ElementId> {
62 self.interactivity.element_id.clone()
63 }
64
65 fn render_once(self) -> Self::Element {
66 self
67 }
68}
69
70impl<V> Styled for Svg<V> {
71 fn style(&mut self) -> &mut StyleRefinement {
72 &mut self.interactivity.base_style
73 }
74}
75
76impl<V> InteractiveElement<V> for Svg<V> {
77 fn interactivity(&mut self) -> &mut Interactivity<V> {
78 &mut self.interactivity
79 }
80}