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