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