xref: /StarryEngine/starry_toolkit/src/widgets/image.rs (revision 2b942a51ce0651f9872b9bf803f3dfc6199e7b63)
1 use std::{
2     cell::{Cell, RefCell},
3     sync::{Arc, Weak},
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     self_ref: RefCell<Weak<Image>>,
16     pub rect: Cell<Rect>,
17     pivot: Cell<PivotType>,
18     pivot_offset: Cell<Vector2>,
19     children: RefCell<Vec<Arc<dyn Widget>>>,
20     parent: RefCell<Option<Arc<dyn Widget>>>,
21     panel_rect: Cell<Option<Rect>>,
22     /// 图像源数据
23     pub image: RefCell<ImageResource>,
24 }
25 
26 impl Image {
27     pub fn new(width: u32, height: u32) -> Arc<Self> {
28         Self::from_image(ImageResource::new(width as i32, height as i32))
29     }
30 
31     pub fn from_color(width: u32, height: u32, color: Color) -> Arc<Self> {
32         Self::from_image(ImageResource::from_color(
33             width as i32,
34             height as i32,
35             color,
36         ))
37     }
38 
39     pub fn from_image(image: ImageResource) -> Arc<Self> {
40         Arc::new(Image {
41             self_ref: RefCell::new(Weak::default()),
42             rect: Cell::new(Rect::new(0, 0, image.width() as u32, image.height() as u32)),
43             pivot: Cell::new(PivotType::TopLeft),
44             pivot_offset: Cell::new(Vector2::new(0, 0)),
45             children: RefCell::new(vec![]),
46             parent: RefCell::new(None),
47             panel_rect: Cell::new(None),
48             image: RefCell::new(image),
49         })
50     }
51 
52     pub fn from_path(path: &[u8]) -> Option<Arc<Self>> {
53         if let Some(image) = ImageResource::from_path(path) {
54             Some(Self::from_image(image))
55         } else {
56             None
57         }
58     }
59 }
60 
61 impl Widget for Image {
62     fn self_ref(&self) -> Arc<dyn Widget> {
63         self.self_ref.borrow().upgrade().unwrap()
64     }
65 
66     fn name(&self) -> &str {
67         "Image"
68     }
69 
70     fn rect(&self) -> &Cell<Rect> {
71         &self.rect
72     }
73 
74     fn pivot(&self) -> &Cell<PivotType> {
75         &self.pivot
76     }
77 
78     fn pivot_offset(&self) -> &Cell<Vector2> {
79         &self.pivot_offset
80     }
81 
82     fn children(&self) -> &RefCell<Vec<Arc<dyn Widget>>> {
83         &self.children
84     }
85 
86     fn parent(&self) -> &RefCell<Option<Arc<dyn Widget>>> {
87         &self.parent
88     }
89 
90     fn panel_rect(&self) -> &Cell<Option<Rect>> {
91         &self.panel_rect
92     }
93 
94     fn draw(&self, renderer: &mut dyn Renderer, _focused: bool) {
95         let rect = self.rect.get();
96         let image = self.image.borrow();
97         renderer.image(rect.x, rect.y, rect.width, rect.height, image.data());
98     }
99 }
100