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