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