use std::{ cell::{Cell, RefCell}, sync::Arc, }; use starry_client::base::{color::Color, renderer::Renderer}; use crate::{base::{point::Point, rect::Rect}, traits::place::Place}; use super::{HorizontalPlacement, VerticalPlacement, Widget}; use crate::starry_server::base::image::Image as ImageAsset; pub struct Image { pub rect: Cell, local_position: Cell, vertical_placement: Cell, horizontal_placement: Cell, children: RefCell>>, /// 图像源数据 pub image: RefCell, } impl Image { pub fn new(width: u32, height: u32) -> Arc { Self::from_image(ImageAsset::new(width as i32, height as i32)) } pub fn from_color(width: u32, height: u32, color: Color) -> Arc { Self::from_image(ImageAsset::from_color(width as i32, height as i32, color)) } pub fn from_image(image: ImageAsset) -> Arc { Arc::new(Image { rect: Cell::new(Rect::new(0, 0, image.width() as u32, image.height() as u32)), local_position: Cell::new(Point::new(0, 0)), vertical_placement: Cell::new(VerticalPlacement::Absolute), horizontal_placement: Cell::new(HorizontalPlacement::Absolute), children: RefCell::new(vec![]), image: RefCell::new(image), }) } pub fn from_path(path: &[u8]) -> Option> { if let Some(image) = ImageAsset::from_path(path) { Some(Self::from_image(image)) } else { None } } } impl Place for Image {} impl Widget for Image { fn name(&self) -> &str { "Image" } fn rect(&self) -> &Cell { &self.rect } fn vertical_placement(&self) -> &Cell { &self.vertical_placement } fn horizontal_placement(&self) -> &Cell { &self.horizontal_placement } fn local_position(&self) -> &Cell { &self.local_position } fn children(&self) -> &RefCell>> { &self.children } fn draw(&self, renderer: &mut dyn Renderer) { let rect = self.rect.get(); let image = self.image.borrow(); renderer.image(rect.x, rect.y, rect.width, rect.height, image.data()); } }