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