xref: /StarryEngine/starry_toolkit/src/widgets/image.rs (revision 49182ea7bc0263215864dd04cd265e345a4af8f5)
1 use std::{
2     cell::{Cell, RefCell},
3     sync::Arc,
4 };
5 
6 use starry_client::base::{color::Color, renderer::Renderer};
7 
8 use crate::{
9     base::{point::Point, rect::Rect},
10     traits::transform::Transform,
11 };
12 
13 use super::{HorizontalPlacement, VerticalPlacement, Widget};
14 
15 use crate::starry_server::base::image::Image as ImageResource;
16 
17 pub struct Image {
18     pub rect: Cell<Rect>,
19     local_position: Cell<Point>,
20     vertical_placement: Cell<VerticalPlacement>,
21     horizontal_placement: Cell<HorizontalPlacement>,
22     children: RefCell<Vec<Arc<dyn Widget>>>,
23     /// 图像源数据
24     pub image: RefCell<ImageResource>,
25 }
26 
27 impl Image {
28     pub fn new(width: u32, height: u32) -> Arc<Self> {
29         Self::from_image(ImageResource::new(width as i32, height as i32))
30     }
31 
32     pub fn from_color(width: u32, height: u32, color: Color) -> Arc<Self> {
33         Self::from_image(ImageResource::from_color(
34             width as i32,
35             height as i32,
36             color,
37         ))
38     }
39 
40     pub fn from_image(image: ImageResource) -> Arc<Self> {
41         Arc::new(Image {
42             rect: Cell::new(Rect::new(0, 0, image.width() as u32, image.height() as u32)),
43             local_position: Cell::new(Point::new(0, 0)),
44             vertical_placement: Cell::new(VerticalPlacement::Absolute),
45             horizontal_placement: Cell::new(HorizontalPlacement::Absolute),
46             children: RefCell::new(vec![]),
47             image: RefCell::new(image),
48         })
49     }
50 
51     pub fn from_path(path: &[u8]) -> Option<Arc<Self>> {
52         if let Some(image) = ImageResource::from_path(path) {
53             Some(Self::from_image(image))
54         } else {
55             None
56         }
57     }
58 }
59 
60 impl Transform for Image {}
61 
62 impl Widget for Image {
63     fn name(&self) -> &str {
64         "Image"
65     }
66 
67     fn rect(&self) -> &Cell<Rect> {
68         &self.rect
69     }
70 
71     fn vertical_placement(&self) -> &Cell<VerticalPlacement> {
72         &self.vertical_placement
73     }
74 
75     fn horizontal_placement(&self) -> &Cell<HorizontalPlacement> {
76         &self.horizontal_placement
77     }
78 
79     fn local_position(&self) -> &Cell<Point> {
80         &self.local_position
81     }
82 
83     fn children(&self) -> &RefCell<Vec<Arc<dyn Widget>>> {
84         &self.children
85     }
86 
87     fn draw(&self, renderer: &mut dyn Renderer, _focused: bool) {
88         let rect = self.rect.get();
89         let image = self.image.borrow();
90         renderer.image(rect.x, rect.y, rect.width, rect.height, image.data());
91     }
92 }
93