xref: /StarryEngine/starry_toolkit/src/widgets/image.rs (revision 6f3c183754d5940a0fbae5cb2a8bc423f3ed1beb)
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 ImageAsset;
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<ImageAsset>,
25 }
26 
27 impl Image {
28     pub fn new(width: u32, height: u32) -> Arc<Self> {
29         Self::from_image(ImageAsset::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(ImageAsset::from_color(width as i32, height as i32, color))
34     }
35 
36     pub fn from_image(image: ImageAsset) -> Arc<Self> {
37         Arc::new(Image {
38             rect: Cell::new(Rect::new(0, 0, image.width() as u32, image.height() as u32)),
39             local_position: Cell::new(Point::new(0, 0)),
40             vertical_placement: Cell::new(VerticalPlacement::Absolute),
41             horizontal_placement: Cell::new(HorizontalPlacement::Absolute),
42             children: RefCell::new(vec![]),
43             image: RefCell::new(image),
44         })
45     }
46 
47     pub fn from_path(path: &[u8]) -> Option<Arc<Self>> {
48         if let Some(image) = ImageAsset::from_path(path) {
49             Some(Self::from_image(image))
50         } else {
51             None
52         }
53     }
54 }
55 
56 impl Transform for Image {}
57 
58 impl Widget for Image {
59     fn name(&self) -> &str {
60         "Image"
61     }
62 
63     fn rect(&self) -> &Cell<Rect> {
64         &self.rect
65     }
66 
67     fn vertical_placement(&self) -> &Cell<VerticalPlacement> {
68         &self.vertical_placement
69     }
70 
71     fn horizontal_placement(&self) -> &Cell<HorizontalPlacement> {
72         &self.horizontal_placement
73     }
74 
75     fn local_position(&self) -> &Cell<Point> {
76         &self.local_position
77     }
78 
79     fn children(&self) -> &RefCell<Vec<Arc<dyn Widget>>> {
80         &self.children
81     }
82 
83     fn draw(&self, renderer: &mut dyn Renderer, _focused: bool) {
84         let rect = self.rect.get();
85         let image = self.image.borrow();
86         renderer.image(rect.x, rect.y, rect.width, rect.height, image.data());
87     }
88 }
89