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