1use std::marker::PhantomData;
2
3use super::Element;
4use crate::{
5 json::{self, json},
6 PaintContext, SceneBuilder, ViewContext,
7};
8use json::ToJson;
9use pathfinder_geometry::{
10 rect::RectF,
11 vector::{vec2f, Vector2F},
12};
13
14pub struct Canvas<V, F>(F, PhantomData<V>);
15
16impl<V, F> Canvas<V, F>
17where
18 F: FnMut(&mut SceneBuilder, RectF, RectF, &mut V, &mut ViewContext<V>),
19{
20 pub fn new(f: F) -> Self {
21 Self(f, PhantomData)
22 }
23}
24
25impl<V: 'static, F> Element<V> for Canvas<V, F>
26where
27 F: 'static + FnMut(&mut SceneBuilder, RectF, RectF, &mut V, &mut ViewContext<V>),
28{
29 type LayoutState = ();
30 type PaintState = ();
31
32 fn layout(
33 &mut self,
34 constraint: crate::SizeConstraint,
35 _: &mut V,
36 _: &mut crate::LayoutContext<V>,
37 ) -> (Vector2F, Self::LayoutState) {
38 let x = if constraint.max.x().is_finite() {
39 constraint.max.x()
40 } else {
41 constraint.min.x()
42 };
43 let y = if constraint.max.y().is_finite() {
44 constraint.max.y()
45 } else {
46 constraint.min.y()
47 };
48 (vec2f(x, y), ())
49 }
50
51 fn paint(
52 &mut self,
53 scene: &mut SceneBuilder,
54 bounds: RectF,
55 visible_bounds: RectF,
56 _: &mut Self::LayoutState,
57 view: &mut V,
58 cx: &mut PaintContext<V>,
59 ) -> Self::PaintState {
60 self.0(scene, bounds, visible_bounds, view, cx)
61 }
62
63 fn rect_for_text_range(
64 &self,
65 _: std::ops::Range<usize>,
66 _: RectF,
67 _: RectF,
68 _: &Self::LayoutState,
69 _: &Self::PaintState,
70 _: &V,
71 _: &ViewContext<V>,
72 ) -> Option<RectF> {
73 None
74 }
75
76 fn debug(
77 &self,
78 bounds: RectF,
79 _: &Self::LayoutState,
80 _: &Self::PaintState,
81 _: &V,
82 _: &ViewContext<V>,
83 ) -> json::Value {
84 json!({"type": "Canvas", "bounds": bounds.to_json()})
85 }
86}