polyhorn_android/raw/
container.rs1use as_any::AsAny;
2use polyhorn_android_sys::{Activity, View};
3use polyhorn_ui::layout::LayoutNode;
4
5use super::{Environment, Platform};
6
7pub trait Container: AsAny + Send {
9 fn mount(&mut self, child: &mut OpaqueContainer, environment: &mut Environment);
11
12 fn unmount(&mut self);
14
15 fn to_view(&self) -> Option<View> {
16 None
17 }
18}
19
20pub struct OpaqueContainer(Option<LayoutNode>, Option<LayoutNode>, Box<dyn Container>);
26
27impl OpaqueContainer {
28 pub fn new<T>(
31 layout: LayoutNode,
32 content_layout: Option<LayoutNode>,
33 view: T,
34 ) -> OpaqueContainer
35 where
36 T: Container,
37 {
38 OpaqueContainer(Some(layout), content_layout, Box::new(view))
39 }
40
41 pub unsafe fn activity(
42 env: *mut std::ffi::c_void,
43 object: *mut std::ffi::c_void,
44 ) -> OpaqueContainer {
45 OpaqueContainer(
46 None,
47 None,
48 Box::new(Activity::with_env(env as _, object as _)),
49 )
50 }
51
52 pub fn layout(&self) -> Option<&LayoutNode> {
54 self.0.as_ref()
55 }
56
57 pub fn content_layout(&self) -> Option<&LayoutNode> {
60 self.1.as_ref()
61 }
62
63 pub fn container(&self) -> &dyn Container {
65 self.2.as_ref()
66 }
67
68 pub fn downcast_mut<T>(&mut self) -> Option<&mut T>
71 where
72 T: 'static,
73 {
74 self.2.as_mut().as_any_mut().downcast_mut::<T>()
75 }
76}
77
78impl polyhorn_core::Container<Platform> for OpaqueContainer {
79 fn mount(&mut self, container: &mut OpaqueContainer, environment: &mut Environment) {
80 if let (Some(child), Some(content)) = (container.layout(), container.content_layout()) {
81 let mut layouter = child.layouter().write().unwrap();
82 layouter.add_child(child.node(), content.node());
83 }
84
85 if let (Some(parent), Some(child)) = (
86 self.content_layout().or_else(|| self.layout()),
87 container.layout(),
88 ) {
89 let mut layouter = parent.layouter().write().unwrap();
90 layouter.add_child(parent.node(), child.node());
91 }
92
93 self.2.mount(container, environment);
94 }
95
96 fn unmount(&mut self) {
97 if let Some(layout) = self.content_layout() {
98 let mut layouter = layout.layouter().write().unwrap();
99 layouter.remove(layout.node());
100 }
101
102 if let Some(layout) = self.layout() {
103 let mut layouter = layout.layouter().write().unwrap();
104 layouter.remove(layout.node());
105 }
106
107 self.2.unmount();
108 }
109}