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