polyhorn_android/components/
image.rs1use polyhorn_android_sys::{Bitmap, BitmapFactory, Env, Rect};
2use polyhorn_core::CommandBuffer;
3use polyhorn_ui::assets::ImageSource;
4use polyhorn_ui::geometry::{Dimension, Size};
5use polyhorn_ui::styles::ViewStyle;
6
7use crate::prelude::*;
8use crate::raw::{Builtin, Container, ContainerID, Environment, OpaqueContainer};
9use crate::{Key, Reference};
10
11impl Container for polyhorn_android_sys::ImageView {
12 fn mount(&mut self, child: &mut OpaqueContainer, environment: &mut Environment) {
13 if let Some(view) = child.container().to_view() {
14 polyhorn_android_sys::ImageView::to_view(self).add_view(environment.env(), &view)
15 }
16 }
17
18 fn unmount(&mut self) {}
19
20 fn to_view(&self) -> Option<polyhorn_android_sys::View> {
21 Some(polyhorn_android_sys::ImageView::to_view(self))
22 }
23}
24
25struct ConcreteImage {
26 image: Option<Bitmap>,
27 size: Size<f32>,
28}
29
30impl Component for Image {
31 fn render(&self, manager: &mut Manager) -> Element {
32 let view_ref: Reference<Option<ContainerID>> = use_reference!(manager, None);
33
34 let image_source = self.source.clone();
35 let tint_color = self.style.image.tint_color.clone();
36
37 let image = match image_source {
38 ImageSource::Asset(_) => todo!(),
39 ImageSource::Bytes(bytes) => {
40 let env = Env::current();
41 let bitmap = BitmapFactory::decode_byte_array(&env, &bytes).unwrap();
42 let size = Size::new(bitmap.width(&env) as f32, bitmap.height(&env) as f32);
43
44 ConcreteImage {
45 image: Some(bitmap),
46 size,
47 }
48 }
49 ImageSource::Placeholder(size) => ConcreteImage { image: None, size },
50 };
51
52 let width = Dimension::Points(image.size.width);
53 let height = Dimension::Points(image.size.height);
54
55 use_layout_effect!(manager, move |link, buffer| {
56 let id = match view_ref.apply(link, |id| id.to_owned()) {
57 Some(id) => id,
58 None => return,
59 };
60
61 buffer.mutate(&[id], move |containers, environment| {
62 let container = &mut containers[0];
63
64 let layout = match container.layout() {
65 Some(layout) => layout.clone(),
66 None => return,
67 };
68
69 let layout = layout.current();
70
71 if let Some(view) = container.downcast_mut::<polyhorn_android_sys::ImageView>() {
72 if let Some(image) = image.image.as_ref() {
73 if let Some(_) = tint_color {
74 todo!();
75 } else {
76 view.set_image_bitmap(environment.env(), image);
77 }
78 }
79
80 view.set_frame(
81 environment.env(),
82 Rect::new(
83 environment.env(),
84 layout.origin.x,
85 layout.origin.y,
86 layout.size.width,
87 layout.size.height,
88 ),
89 );
90 }
91 });
92 });
93
94 Element::builtin(
95 Key::new(()),
96 Builtin::ImageView(ViewStyle {
97 size: Size { width, height },
98 ..Default::default()
99 }),
100 manager.children(),
101 Some(view_ref.weak(manager)),
102 )
103 }
104}