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