polyhorn_android/raw/
builtin.rs

1use polyhorn_android_sys::{ImageView, View};
2use polyhorn_ui::geometry::{Dimension, Size};
3use polyhorn_ui::layout::LayoutNode;
4use polyhorn_ui::styles::{FlexDirection, Position, Relative, ViewStyle};
5
6use super::{Container, Environment, OpaqueContainer, Platform};
7
8#[derive(Clone, Debug)]
9pub enum Builtin {
10    ImageView(ViewStyle),
11    KeyboardAvoidingView,
12    Label,
13    ScrollView,
14    TextInput,
15    View(ViewStyle),
16    Window,
17}
18
19impl polyhorn_core::Builtin<Platform> for Builtin {
20    fn instantiate(
21        &self,
22        _parent: &mut OpaqueContainer,
23        environment: &mut Environment,
24    ) -> OpaqueContainer {
25        let layout = match self {
26            Builtin::Label => LayoutNode::leaf(environment.layout_tree().clone()),
27            _ => LayoutNode::new(environment.layout_tree().clone()),
28        };
29
30        match self {
31            Builtin::ImageView(_) => {
32                let view = ImageView::new(environment.env(), environment.activity());
33                let container = OpaqueContainer::new(layout, None, view);
34                container
35            }
36            Builtin::View(_) => {
37                let view = View::new(environment.env(), environment.activity());
38                let container = OpaqueContainer::new(layout, None, view);
39                container
40            }
41            Builtin::Window => {
42                environment
43                    .layout_tree()
44                    .write()
45                    .unwrap()
46                    .roots_mut()
47                    .push(layout.node());
48
49                let view = View::new(environment.env(), environment.activity());
50                let container = OpaqueContainer::new(layout, None, view);
51                container
52            }
53            _ => todo!(),
54        }
55    }
56
57    fn update(&self, container: &mut OpaqueContainer, environment: &mut Environment) {
58        match self {
59            &Builtin::ImageView(style) => {
60                container.layout().unwrap().set_style(style);
61            }
62            &Builtin::View(style) => {
63                container.layout().unwrap().set_style(style);
64            }
65            &Builtin::Window => {
66                let activity = environment.activity();
67                let env = environment.env();
68                let frame = activity.bounds(&env);
69
70                container.layout().unwrap().set_style(ViewStyle {
71                    position: Position::Relative(Relative {
72                        flex_shrink: 0.0,
73                        flex_grow: 0.0,
74                        ..Default::default()
75                    }),
76                    flex_direction: FlexDirection::Column,
77                    size: Size {
78                        width: Dimension::Points(frame.width(&env).ceil() as _),
79                        height: Dimension::Points(frame.height(&env).ceil() as _),
80                    },
81                    ..Default::default()
82                });
83            }
84            _ => {}
85        }
86    }
87}
88
89impl Container for polyhorn_android_sys::Activity {
90    fn mount(&mut self, child: &mut OpaqueContainer, environment: &mut Environment) {
91        if let Some(view) = child.downcast_mut::<View>() {
92            self.set_content_view(environment.env(), view);
93        }
94    }
95
96    fn unmount(&mut self) {
97        // The activity is never unmounted.
98    }
99}