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