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 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}