xref: /StarryEngine/starry_server/src/base/window.rs (revision 731cae0674923fcc85c6e683a2eee596eb642796)
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