1use refineable::Refineable as _;
2
3use crate::{Bounds, Element, IntoElement, Pixels, Style, StyleRefinement, Styled, WindowContext};
4
5pub fn canvas(callback: impl 'static + FnOnce(&Bounds<Pixels>, &mut WindowContext)) -> Canvas {
6 Canvas {
7 paint_callback: Some(Box::new(callback)),
8 style: StyleRefinement::default(),
9 }
10}
11
12pub struct Canvas {
13 paint_callback: Option<Box<dyn FnOnce(&Bounds<Pixels>, &mut WindowContext)>>,
14 style: StyleRefinement,
15}
16
17impl IntoElement for Canvas {
18 type Element = Self;
19
20 fn element_id(&self) -> Option<crate::ElementId> {
21 None
22 }
23
24 fn into_element(self) -> Self::Element {
25 self
26 }
27}
28
29impl Element for Canvas {
30 type State = Style;
31
32 fn request_layout(
33 &mut self,
34 _: Option<Self::State>,
35 cx: &mut WindowContext,
36 ) -> (crate::LayoutId, Self::State) {
37 let mut style = Style::default();
38 style.refine(&self.style);
39 let layout_id = cx.request_layout(&style, []);
40 (layout_id, style)
41 }
42
43 fn paint(&mut self, bounds: Bounds<Pixels>, style: &mut Style, cx: &mut WindowContext) {
44 style.paint(bounds, cx, |cx| {
45 (self.paint_callback.take().unwrap())(&bounds, cx)
46 });
47 }
48}
49
50impl Styled for Canvas {
51 fn style(&mut self) -> &mut crate::StyleRefinement {
52 &mut self.style
53 }
54}