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