Skip to main content

sequoia_view/
any.rs

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}