Skip to main content

sequoia_view/
any.rs

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}