use std::{ cell::{Cell, RefCell}, sync::{Arc, Weak}, }; use starry_client::base::{color::Color, renderer::Renderer}; use crate::base::{rect::Rect, vector2::Vector2}; use super::{PivotType, Widget}; use crate::starry_server::base::image::Image as ImageResource; pub struct Image { self_ref: RefCell>, pub rect: Cell, pivot: Cell, pivot_offset: Cell, children: RefCell>>, parent: RefCell>>, panel_rect: Cell>, /// 图像源数据 pub image: RefCell, } impl Image { pub fn new(width: u32, height: u32) -> Arc { Self::from_image(ImageResource::new(width as i32, height as i32)) } pub fn from_color(width: u32, height: u32, color: Color) -> Arc { Self::from_image(ImageResource::from_color( width as i32, height as i32, color, )) } pub fn from_image(image: ImageResource) -> Arc { Arc::new(Image { self_ref: RefCell::new(Weak::default()), rect: Cell::new(Rect::new(0, 0, image.width() as u32, image.height() as u32)), pivot: Cell::new(PivotType::TopLeft), pivot_offset: Cell::new(Vector2::new(0, 0)), children: RefCell::new(vec![]), parent: RefCell::new(None), panel_rect: Cell::new(None), image: RefCell::new(image), }) } pub fn from_path(path: &[u8]) -> Option> { if let Some(image) = ImageResource::from_path(path) { Some(Self::from_image(image)) } else { None } } } impl Widget for Image { fn self_ref(&self) -> Arc { self.self_ref.borrow().upgrade().unwrap() } fn name(&self) -> &str { "Image" } fn rect(&self) -> &Cell { &self.rect } fn pivot(&self) -> &Cell { &self.pivot } fn pivot_offset(&self) -> &Cell { &self.pivot_offset } fn children(&self) -> &RefCell>> { &self.children } fn parent(&self) -> &RefCell>> { &self.parent } fn panel_rect(&self) -> &Cell> { &self.panel_rect } fn draw(&self, renderer: &mut dyn Renderer, _focused: bool) { let rect = self.rect.get(); let image = self.image.borrow(); renderer.image(rect.x, rect.y, rect.width, rect.height, image.data()); } }