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