1 use starry_client::base::event::Event; 2 3 use crate::core::SCREEN_HEIGHT; 4 5 use super::{display::Display, image::Image, rect::Rect}; 6 7 /// 窗口按Z值排序的模式 8 #[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord)] 9 pub enum WindowZOrderMode { 10 /// 背景窗口 11 Back, 12 /// 普通窗口 13 Normal, 14 /// 前景窗口 15 Front, 16 } 17 18 /// 服务端的窗口类,与客户端的窗口类一一对应 19 #[allow(dead_code)] 20 pub struct Window { 21 /// 窗口左上角x坐标 22 pub x: i32, 23 /// 窗口左上角y坐标 24 pub y: i32, 25 /// 窗口大小系数 26 pub scale: i32, 27 /// 窗口标题 28 pub title: String, 29 // pub asynchronous: bool, 30 // pub barderless: bool, 31 // pub resizable: bool, 32 /// 是否透明 33 pub transparent: bool, 34 // pub unclosable: bool, 35 /// 排序模式 36 pub zorder: WindowZOrderMode, 37 38 /// 窗体图像 39 pub image: Image, 40 /// 窗口标题图像(聚焦) 41 // pub title_image: Image, 42 /// 窗口标题图像(非聚焦) 43 // pub title_image_unfocused: Image, 44 45 /// 事件数组 46 pub events: Vec<Event>, 47 // TODO 增加所需字段 48 } 49 50 impl Window { 51 pub fn new(x: i32, y: i32, _w: i32, _h: i32, scale: i32, image_path: &[u8]) -> Window { 52 Window { 53 x: x, 54 y: y, 55 scale: scale, 56 title: String::new(), 57 transparent: false, 58 zorder: WindowZOrderMode::Normal, 59 image: Image::from_path(image_path) 60 .unwrap_or(Image::new(SCREEN_HEIGHT as i32, SCREEN_HEIGHT as i32)), 61 events: Vec::new(), 62 } 63 } 64 65 /// 窗体宽度 66 pub fn width(&self) -> i32 { 67 self.image.width() 68 } 69 70 /// 窗体高度 71 pub fn height(&self) -> i32 { 72 self.image.height() 73 } 74 75 /// 返回窗体对应矩形 76 pub fn rect(&self) -> Rect { 77 Rect::new(self.x, self.y, self.width(), self.height()) 78 } 79 80 // TODO 81 // pub fn title_rect(&self) -> Rect {} 82 83 /// # 函数功能 84 /// 渲染窗体到显示窗口中 85 /// 86 /// ## 参数 87 /// - display: 展示窗口 88 /// - rect: 渲染的矩形区域(绝对位置) 89 pub fn draw(&mut self, display: &mut Display, rect: &Rect) { 90 let self_rect = self.rect(); 91 let intersect = self_rect.intersection(rect); 92 if !intersect.is_empty() { 93 // (半)透明窗口 94 if self.transparent { 95 display.roi(&intersect).blend( 96 &self 97 .image 98 .roi(&intersect.offset(-self_rect.left(), -self_rect.top())), 99 ); 100 } 101 // 不透明窗口 102 else { 103 display.roi(&intersect).cover( 104 &self 105 .image 106 .roi(&intersect.offset(-self_rect.left(), -self_rect.top())), 107 ); 108 } 109 } 110 } 111 } 112