1use std::any::{Any, TypeId};
2use std::rc::Rc;
3
4use sequoia_core::{Rect, Size, Vec2};
5use sequoia_input::{CursorIcon, Event};
6use sequoia_style::{Filter, VisualState};
7
8use crate::dnd::{DragEnd, DragPayload, DropPosition};
9use crate::runtime::{ElementId, Runtime};
10use crate::surface::SurfaceInputBinding;
11use crate::view::{EventCtx, PaintCtx, View};
12use sequoia_layout::{
13 ContainerStyle, DockStyle, GridPlacement, GridStyle, LayoutCtx, LayoutStyle, WrapStyle,
14};
15
16pub(crate) trait ErasedView: 'static {
17 fn view_type(&self) -> TypeId;
18 fn type_name(&self) -> &'static str;
19 fn is_leaf(&self) -> bool;
20 fn children_override(&self) -> Option<Vec<AnyView>>;
21 fn keyed_children(&self) -> Option<Vec<(u64, AnyView)>>;
22 fn call_body(&self) -> AnyView;
23 fn layout_style_erased(&self) -> LayoutStyle;
24 fn layout_style_ctx_erased(&self, rt: &Runtime, el: ElementId) -> LayoutStyle;
25 fn container(&self) -> Option<ContainerStyle>;
26 fn grid(&self) -> Option<GridStyle>;
27 fn dock(&self) -> Option<DockStyle>;
28 fn wrap(&self) -> Option<WrapStyle>;
29 fn grid_placement(&self) -> Option<GridPlacement>;
30 fn grid_placements(&self) -> Option<Vec<GridPlacement>>;
31 fn flex_weights(&self) -> Option<Vec<f32>>;
32 fn intrinsic_size(&self, ctx: &mut LayoutCtx) -> Option<Size>;
33 fn contain_size_erased(&self) -> bool;
34 fn arrange_override_erased(
35 &self,
36 rt: &Runtime,
37 el: ElementId,
38 rect: Rect,
39 ctx: &mut LayoutCtx,
40 ) -> bool;
41 fn clip_self_erased(&self) -> bool;
42 fn clip_radius_erased(&self) -> f32;
43 fn paint_opacity_erased(&self) -> Option<f32>;
44 fn paint_offset_erased(&self) -> Vec2;
45 fn paint_opacity_ctx_erased(&self, rt: &Runtime, el: ElementId) -> Option<f32>;
46 fn paint_offset_ctx_erased(&self, rt: &Runtime, el: ElementId) -> Vec2;
47 fn paint_scale_erased(&self) -> f32;
48 fn paint_scale_ctx_erased(&self, rt: &Runtime, el: ElementId) -> f32;
49 fn paint_rotation_erased(&self) -> f32;
50 fn paint_rotation_ctx_erased(&self, rt: &Runtime, el: ElementId) -> f32;
51
52 fn foreground_filter_erased(&self) -> Option<Filter>;
53 fn surface_target_erased(&self) -> Option<Rc<dyn Any>>;
54 fn surface_input_erased(&self) -> Option<SurfaceInputBinding>;
55 fn on_event_erased(&self, event: &Event, ctx: &mut EventCtx);
56 fn captures_pointer_erased(&self) -> bool;
57 fn captures_pointer_ctx_erased(&self, rt: &Runtime, el: ElementId) -> bool;
58 fn reuse_state_erased(&self, old: &dyn ErasedView);
59 fn as_any(&self) -> &dyn Any;
60 fn hit_testable_erased(&self) -> bool;
61 fn test_id_erased(&self) -> Option<String>;
62 fn focusable_erased(&self) -> bool;
63 fn focus_trap_erased(&self) -> bool;
64 fn accepts_tab_erased(&self) -> bool;
65 fn cursor_icon_erased(&self, state: VisualState) -> CursorIcon;
66 fn has_visual_state_erased(&self) -> bool;
67 fn wants_hover_updates_erased(&self) -> bool;
68 fn accessibility_erased(&self) -> Option<crate::a11y::Accessible>;
69 fn paint_self_erased(&self, ctx: &mut PaintCtx);
70 fn paint_foreground_erased(&self, ctx: &mut PaintCtx);
71 fn accepts_drop_erased(&self, payload: &DragPayload) -> bool;
72 fn on_drag_start_erased(&self, ctx: &mut EventCtx);
73 fn on_drag_over_erased(&self, pos: DropPosition, ctx: &mut EventCtx);
74 fn on_drop_erased(&self, pos: DropPosition, ctx: &mut EventCtx);
75 fn on_drag_end_erased(&self, end: DragEnd, ctx: &mut EventCtx);
76 fn as_any_rc(self: Rc<Self>) -> Rc<dyn Any>;
77 fn on_mount(&self);
78 fn on_unmount(&self);
79}
80
81impl<V: View + 'static> ErasedView for V {
82 fn view_type(&self) -> TypeId {
83 TypeId::of::<V>()
84 }
85 fn type_name(&self) -> &'static str {
86 std::any::type_name::<V>()
87 }
88 fn is_leaf(&self) -> bool {
89 View::is_leaf(self)
90 }
91 fn children_override(&self) -> Option<Vec<AnyView>> {
92 View::children_override(self)
93 }
94 fn keyed_children(&self) -> Option<Vec<(u64, AnyView)>> {
95 View::keyed_children(self)
96 }
97 fn call_body(&self) -> AnyView {
98 AnyView::new(View::body(self))
99 }
100 fn layout_style_erased(&self) -> LayoutStyle {
101 View::layout_style(self)
102 }
103 fn layout_style_ctx_erased(&self, rt: &Runtime, el: ElementId) -> LayoutStyle {
104 View::layout_style_ctx(self, rt, el)
105 }
106 fn container(&self) -> Option<ContainerStyle> {
107 View::container(self)
108 }
109 fn grid(&self) -> Option<GridStyle> {
110 View::grid(self)
111 }
112 fn dock(&self) -> Option<DockStyle> {
113 View::dock(self)
114 }
115 fn wrap(&self) -> Option<WrapStyle> {
116 View::wrap(self)
117 }
118 fn grid_placement(&self) -> Option<GridPlacement> {
119 View::grid_placement(self)
120 }
121 fn grid_placements(&self) -> Option<Vec<GridPlacement>> {
122 View::grid_placements(self)
123 }
124 fn flex_weights(&self) -> Option<Vec<f32>> {
125 View::flex_weights(self).map(|s| s.to_vec())
126 }
127 fn intrinsic_size(&self, ctx: &mut LayoutCtx) -> Option<Size> {
128 View::intrinsic_size(self, ctx)
129 }
130 fn contain_size_erased(&self) -> bool {
131 View::contain_size(self)
132 }
133 fn arrange_override_erased(
134 &self,
135 rt: &Runtime,
136 el: ElementId,
137 rect: Rect,
138 ctx: &mut LayoutCtx,
139 ) -> bool {
140 View::arrange_override(self, rt, el, rect, ctx)
141 }
142 fn clip_self_erased(&self) -> bool {
143 View::clip_self(self)
144 }
145 fn clip_radius_erased(&self) -> f32 {
146 View::clip_radius(self)
147 }
148 fn paint_opacity_erased(&self) -> Option<f32> {
149 View::paint_opacity(self)
150 }
151 fn paint_offset_erased(&self) -> Vec2 {
152 View::paint_offset(self)
153 }
154 fn paint_opacity_ctx_erased(&self, rt: &Runtime, el: ElementId) -> Option<f32> {
155 View::paint_opacity_ctx(self, rt, el)
156 }
157 fn paint_offset_ctx_erased(&self, rt: &Runtime, el: ElementId) -> Vec2 {
158 View::paint_offset_ctx(self, rt, el)
159 }
160 fn paint_scale_erased(&self) -> f32 {
161 View::paint_scale(self)
162 }
163 fn paint_scale_ctx_erased(&self, rt: &Runtime, el: ElementId) -> f32 {
164 View::paint_scale_ctx(self, rt, el)
165 }
166 fn paint_rotation_erased(&self) -> f32 {
167 View::paint_rotation(self)
168 }
169 fn paint_rotation_ctx_erased(&self, rt: &Runtime, el: ElementId) -> f32 {
170 View::paint_rotation_ctx(self, rt, el)
171 }
172 fn foreground_filter_erased(&self) -> Option<Filter> {
173 View::foreground_filter(self)
174 }
175 fn surface_target_erased(&self) -> Option<Rc<dyn Any>> {
176 View::surface_target(self)
177 }
178 fn surface_input_erased(&self) -> Option<SurfaceInputBinding> {
179 View::surface_input(self)
180 }
181 fn on_event_erased(&self, event: &Event, ctx: &mut EventCtx) {
182 View::on_event(self, event, ctx);
183 }
184 fn captures_pointer_erased(&self) -> bool {
185 View::captures_pointer(self)
186 }
187 fn captures_pointer_ctx_erased(&self, rt: &Runtime, el: ElementId) -> bool {
188 View::captures_pointer_ctx(self, rt, el)
189 }
190 fn reuse_state_erased(&self, old: &dyn ErasedView) {
191 if let (Some(me), Some(prev)) = (
192 self.as_any().downcast_ref::<V>(),
193 old.as_any().downcast_ref::<V>(),
194 ) {
195 View::reuse_state(me, prev);
196 }
197 }
198 fn as_any(&self) -> &dyn Any {
199 self
200 }
201 fn hit_testable_erased(&self) -> bool {
202 View::hit_testable(self) && View::layout_style(self).hit_testable
203 }
204 fn test_id_erased(&self) -> Option<String> {
205 View::test_id(self)
206 }
207 fn focusable_erased(&self) -> bool {
208 View::focusable(self)
209 }
210 fn focus_trap_erased(&self) -> bool {
211 View::focus_trap(self)
212 }
213 fn accepts_tab_erased(&self) -> bool {
214 View::accepts_tab(self)
215 }
216 fn cursor_icon_erased(&self, state: VisualState) -> CursorIcon {
217 View::cursor_icon(self, state)
218 }
219 fn has_visual_state_erased(&self) -> bool {
220 View::has_visual_state(self)
221 }
222 fn wants_hover_updates_erased(&self) -> bool {
223 View::wants_hover_updates(self)
224 }
225 fn accessibility_erased(&self) -> Option<crate::a11y::Accessible> {
226 View::accessibility(self)
227 }
228 fn paint_self_erased(&self, ctx: &mut PaintCtx) {
229 View::paint_self(self, ctx);
230 }
231 fn paint_foreground_erased(&self, ctx: &mut PaintCtx) {
232 View::paint_foreground(self, ctx);
233 }
234 fn accepts_drop_erased(&self, payload: &DragPayload) -> bool {
235 View::accepts_drop(self, payload)
236 }
237 fn on_drag_start_erased(&self, ctx: &mut EventCtx) {
238 View::on_drag_start(self, ctx);
239 }
240 fn on_drag_over_erased(&self, pos: DropPosition, ctx: &mut EventCtx) {
241 View::on_drag_over(self, pos, ctx);
242 }
243 fn on_drop_erased(&self, pos: DropPosition, ctx: &mut EventCtx) {
244 View::on_drop(self, pos, ctx);
245 }
246 fn on_drag_end_erased(&self, end: DragEnd, ctx: &mut EventCtx) {
247 View::on_drag_end(self, end, ctx);
248 }
249 fn as_any_rc(self: Rc<Self>) -> Rc<dyn Any> {
250 self
251 }
252 fn on_mount(&self) {
253 View::on_mount(self)
254 }
255 fn on_unmount(&self) {
256 View::on_unmount(self)
257 }
258}
259
260pub struct AnyView(Rc<dyn ErasedView>);
261
262impl AnyView {
263 pub fn new<V: View + 'static>(view: V) -> Self {
264 Self(Rc::new(view))
265 }
266
267 pub fn inner_layout_style(&self) -> LayoutStyle {
268 self.0.layout_style_erased()
269 }
270 pub(crate) fn into_inner(self) -> Rc<dyn ErasedView> {
271 self.0
272 }
273 pub(crate) fn clone_inner(&self) -> Rc<dyn ErasedView> {
274 Rc::clone(&self.0)
275 }
276}
277
278impl Clone for AnyView {
279 fn clone(&self) -> Self {
280 Self(Rc::clone(&self.0))
281 }
282}
283
284impl View for AnyView {
285 fn body(&self) -> impl View + 'static {
286 crate::views::Unit
287 }
288 fn arrange_override(
289 &self,
290 rt: &Runtime,
291 el: ElementId,
292 rect: Rect,
293 ctx: &mut LayoutCtx,
294 ) -> bool {
295 self.0.arrange_override_erased(rt, el, rect, ctx)
296 }
297 fn clip_self(&self) -> bool {
298 self.0.clip_self_erased()
299 }
300 fn clip_radius(&self) -> f32 {
301 self.0.clip_radius_erased()
302 }
303 fn paint_opacity(&self) -> Option<f32> {
304 self.0.paint_opacity_erased()
305 }
306 fn paint_offset(&self) -> Vec2 {
307 self.0.paint_offset_erased()
308 }
309 fn paint_opacity_ctx(&self, rt: &Runtime, el: ElementId) -> Option<f32> {
310 self.0.paint_opacity_ctx_erased(rt, el)
311 }
312 fn paint_offset_ctx(&self, rt: &Runtime, el: ElementId) -> Vec2 {
313 self.0.paint_offset_ctx_erased(rt, el)
314 }
315 fn paint_scale(&self) -> f32 {
316 self.0.paint_scale_erased()
317 }
318 fn paint_scale_ctx(&self, rt: &Runtime, el: ElementId) -> f32 {
319 self.0.paint_scale_ctx_erased(rt, el)
320 }
321 fn paint_rotation(&self) -> f32 {
322 self.0.paint_rotation_erased()
323 }
324 fn paint_rotation_ctx(&self, rt: &Runtime, el: ElementId) -> f32 {
325 self.0.paint_rotation_ctx_erased(rt, el)
326 }
327 fn foreground_filter(&self) -> Option<Filter> {
328 self.0.foreground_filter_erased()
329 }
330 fn surface_target(&self) -> Option<Rc<dyn Any>> {
331 self.0.surface_target_erased()
332 }
333 fn surface_input(&self) -> Option<SurfaceInputBinding> {
334 self.0.surface_input_erased()
335 }
336 fn on_event(&self, event: &Event, ctx: &mut EventCtx) {
337 self.0.on_event_erased(event, ctx);
338 }
339 fn captures_pointer(&self) -> bool {
340 self.0.captures_pointer_erased()
341 }
342 fn captures_pointer_ctx(&self, rt: &Runtime, el: ElementId) -> bool {
343 self.0.captures_pointer_ctx_erased(rt, el)
344 }
345 fn reuse_state(&self, _old: &Self) {}
346 fn hit_testable(&self) -> bool {
347 self.0.hit_testable_erased()
348 }
349 fn test_id(&self) -> Option<String> {
350 self.0.test_id_erased()
351 }
352 fn focusable(&self) -> bool {
353 self.0.focusable_erased()
354 }
355 fn cursor_icon(&self, state: VisualState) -> CursorIcon {
356 self.0.cursor_icon_erased(state)
357 }
358 fn has_visual_state(&self) -> bool {
359 self.0.has_visual_state_erased()
360 }
361 fn wants_hover_updates(&self) -> bool {
362 self.0.wants_hover_updates_erased()
363 }
364 fn paint_self(&self, ctx: &mut PaintCtx) {
365 self.0.paint_self_erased(ctx)
366 }
367 fn paint_foreground(&self, ctx: &mut PaintCtx) {
368 self.0.paint_foreground_erased(ctx)
369 }
370}