1 use std::{ 2 any::Any, 3 cell::{Cell, RefCell}, 4 sync::{Arc, Weak}, 5 }; 6 7 use starry_client::base::{color::Color, renderer::Renderer}; 8 9 use crate::{ 10 base::{panel::Panel, rect::Rect, vector2::Vector2}, 11 util::get_local_rect, 12 }; 13 14 use super::{PivotType, Widget}; 15 16 use crate::starry_server::base::image::Image as ImageResource; 17 18 pub struct Image { 19 self_ref: RefCell<Weak<Image>>, 20 rect: Cell<Rect>, 21 pivot: Cell<PivotType>, 22 pivot_offset: Cell<Vector2>, 23 children: RefCell<Vec<Arc<dyn Widget>>>, 24 parent: RefCell<Option<Arc<dyn Widget>>>, 25 panel: RefCell<Option<Arc<Panel>>>, 26 /// 图像源数据 27 image: RefCell<ImageResource>, 28 } 29 30 impl Image { 31 pub fn new(width: u32, height: u32) -> Arc<Self> { 32 Self::new_from_image(ImageResource::new(width as i32, height as i32)) 33 } 34 35 pub fn new_from_color(width: u32, height: u32, color: Color) -> Arc<Self> { 36 Self::new_from_image(ImageResource::from_color( 37 width as i32, 38 height as i32, 39 color, 40 )) 41 } 42 43 pub fn new_from_image(image: ImageResource) -> Arc<Self> { 44 let image = Arc::new(Image { 45 self_ref: RefCell::new(Weak::default()), 46 rect: Cell::new(Rect::new(0, 0, image.width() as u32, image.height() as u32)), 47 pivot: Cell::new(PivotType::TopLeft), 48 pivot_offset: Cell::new(Vector2::new(0, 0)), 49 children: RefCell::new(vec![]), 50 parent: RefCell::new(None), 51 panel: RefCell::new(None), 52 image: RefCell::new(image), 53 }); 54 55 (*image.self_ref.borrow_mut()) = Arc::downgrade(&image); 56 57 return image; 58 } 59 60 pub fn new_from_path(path: &[u8]) -> Option<Arc<Self>> { 61 if let Some(image) = ImageResource::from_path(path) { 62 Some(Self::new_from_image(image)) 63 } else { 64 None 65 } 66 } 67 68 pub fn set_from_path(&self, path: &[u8]) { 69 if let Some(image) = ImageResource::from_path(path) { 70 (*self.image.borrow_mut()) = image; 71 } else { 72 println!("[Error] Image failed to set image"); 73 } 74 } 75 76 pub fn set_from_color(&self, color: Color) { 77 (*self.image.borrow_mut()) = ImageResource::from_color( 78 self.rect.get().width as i32, 79 self.rect.get().height as i32, 80 color, 81 ); 82 } 83 } 84 85 impl Widget for Image { 86 fn self_ref(&self) -> Arc<dyn Widget> { 87 self.self_ref.borrow().upgrade().unwrap() 88 } 89 90 fn as_any_ref(&self) -> &dyn Any { 91 self 92 } 93 94 fn name(&self) -> &str { 95 "Image" 96 } 97 98 fn rect(&self) -> &Cell<Rect> { 99 &self.rect 100 } 101 102 fn pivot(&self) -> &Cell<PivotType> { 103 &self.pivot 104 } 105 106 fn pivot_offset(&self) -> &Cell<Vector2> { 107 &self.pivot_offset 108 } 109 110 fn children(&self) -> &RefCell<Vec<Arc<dyn Widget>>> { 111 &self.children 112 } 113 114 fn parent(&self) -> &RefCell<Option<Arc<dyn Widget>>> { 115 &self.parent 116 } 117 118 fn panel(&self) -> &RefCell<Option<Arc<Panel>>> { 119 &self.panel 120 } 121 122 fn draw(&self, renderer: &mut dyn Renderer, _focused: bool) { 123 let image = self.image.borrow(); 124 if self.panel().borrow().is_some() { 125 let panel_rect = self.panel.borrow().clone().unwrap().rect(); 126 let local_rect = get_local_rect(self.rect.get(), panel_rect); 127 renderer.image( 128 local_rect.x, 129 local_rect.y, 130 local_rect.width, 131 local_rect.height, 132 image.data(), 133 ); 134 } else { 135 println!("[Error] Image do not belong to any panel!"); 136 } 137 } 138 } 139