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 initialize(
41 &mut self,
42 _view_state: &mut V,
43 element_state: Option<Self::ElementState>,
44 cx: &mut ViewContext<V>,
45 ) -> Self::ElementState {
46 self.interactivity.initialize(element_state, cx)
47 }
48
49 fn layout(
50 &mut self,
51 _view_state: &mut V,
52 element_state: &mut Self::ElementState,
53 cx: &mut ViewContext<V>,
54 ) -> LayoutId {
55 self.interactivity.layout(element_state, cx, |style, cx| {
56 cx.request_layout(&style, None)
57 })
58 }
59
60 fn paint(
61 &mut self,
62 bounds: Bounds<Pixels>,
63 _view_state: &mut V,
64 element_state: &mut Self::ElementState,
65 cx: &mut ViewContext<V>,
66 ) where
67 Self: Sized,
68 {
69 self.interactivity
70 .paint(bounds, bounds.size, element_state, cx, |style, _, cx| {
71 if let Some((path, color)) = self.path.as_ref().zip(style.text.color) {
72 cx.paint_svg(bounds, path.clone(), color).log_err();
73 }
74 })
75 }
76}
77
78impl<V> Styled for Svg<V> {
79 fn style(&mut self) -> &mut StyleRefinement {
80 &mut self.interactivity.base_style
81 }
82}
83
84impl<V> InteractiveComponent<V> for Svg<V> {
85 fn interactivity(&mut self) -> &mut Interactivity<V> {
86 &mut self.interactivity
87 }
88}