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