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