gpui_authoring/elements/
canvas.rs1use refineable::Refineable as _;
2
3use crate::{
4 App, Bounds, Element, ElementId, GlobalElementId, IntoElement, Pixels, Style, StyleRefinement,
5 Styled, Window,
6};
7
8pub fn canvas<T>(
11 prepaint: impl 'static + FnOnce(Bounds<Pixels>, &mut Window, &mut App) -> T,
12 paint: impl 'static + FnOnce(Bounds<Pixels>, T, &mut Window, &mut App),
13) -> Canvas<T> {
14 Canvas {
15 prepaint: Some(Box::new(prepaint)),
16 paint: Some(Box::new(paint)),
17 style: StyleRefinement::default(),
18 }
19}
20
21pub struct Canvas<T> {
24 prepaint: Option<Box<dyn FnOnce(Bounds<Pixels>, &mut Window, &mut App) -> T>>,
25 paint: Option<Box<dyn FnOnce(Bounds<Pixels>, T, &mut Window, &mut App)>>,
26 style: StyleRefinement,
27}
28
29impl<T: 'static> IntoElement for Canvas<T> {
30 type Element = Self;
31
32 fn into_element(self) -> Self::Element {
33 self
34 }
35}
36
37impl<T: 'static> Element for Canvas<T> {
38 type RequestLayoutState = Style;
39 type PrepaintState = Option<T>;
40
41 fn id(&self) -> Option<ElementId> {
42 None
43 }
44
45 fn source_location(&self) -> Option<&'static core::panic::Location<'static>> {
46 None
47 }
48
49 fn request_layout(
50 &mut self,
51 _id: Option<&GlobalElementId>,
52 window: &mut Window,
53 cx: &mut App,
54 ) -> (crate::LayoutId, Self::RequestLayoutState) {
55 let mut style = Style::default();
56 style.refine(&self.style);
57 let layout_id = window.request_layout(style.clone(), [], cx);
58 (layout_id, style)
59 }
60
61 fn prepaint(
62 &mut self,
63 _id: Option<&GlobalElementId>,
64 bounds: Bounds<Pixels>,
65 _request_layout: &mut Style,
66 window: &mut Window,
67 cx: &mut App,
68 ) -> Option<T> {
69 Some(self.prepaint.take().unwrap()(bounds, window, cx))
70 }
71
72 fn paint(
73 &mut self,
74 _id: Option<&GlobalElementId>,
75 bounds: Bounds<Pixels>,
76 style: &mut Style,
77 prepaint: &mut Self::PrepaintState,
78 window: &mut Window,
79 cx: &mut App,
80 ) {
81 let prepaint = prepaint.take().unwrap();
82 style.paint(bounds, window, cx, |window, cx| {
83 (self.paint.take().unwrap())(bounds, prepaint, window, cx)
84 });
85 }
86}
87
88impl<T> Styled for Canvas<T> {
89 fn style(&mut self) -> &mut crate::StyleRefinement {
90 &mut self.style
91 }
92}