xref: /StarryEngine/starry_server/src/core/window_manager.rs (revision 49182ea7bc0263215864dd04cd265e345a4af8f5)
1 use std::{
2     cmp,
3     collections::{BTreeMap, VecDeque},
4     sync::{Arc, RwLock},
5 };
6 
7 use starry_client::base::event::{Event, EventOption, MouseRelativeEvent, MouseUpdateEvent};
8 
9 use crate::{
10     base::{
11         rect::Rect,
12         window::{Window, WindowZOrderMode},
13     },
14     core::{SCREEN_HEIGHT, SCREEN_WIDTH},
15 };
16 
17 use super::{compositor::compositor, starry_server};
18 
19 static mut WINDOW_MANAGER: Option<Arc<WindowManager>> = None;
20 
21 pub fn window_manager() -> Option<Arc<WindowManager>> {
22     unsafe { WINDOW_MANAGER.clone() }
23 }
24 
25 /// 鼠标样式
26 #[allow(dead_code)]
27 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
28 pub enum CursorKind {
29     /// 无/不显示
30     None,
31     /// 默认状态
32     Normal,
33     /// 左下角
34     BottomLeftCorner,
35     /// 右下角
36     BottomRightCorner,
37     /// 下边界
38     BottomSide,
39     /// 左边界
40     LeftSide,
41     /// 右边界
42     RightSide,
43 }
44 
45 /// 窗口管理器
46 #[allow(dead_code)]
47 pub struct WindowManager {
48     /// 数据锁
49     pub data: RwLock<WindowManagerData>,
50 }
51 
52 #[allow(dead_code)]
53 pub struct WindowManagerData {
54     /// 下一个窗口的id值
55     next_id: isize,
56     /// TODO
57     _hover: Option<usize>,
58     /// 窗口顺序
59     pub order: VecDeque<usize>,
60     /// 窗口顺序信息(下标index,模式,窗口id)
61     pub zbuffer: Vec<(usize, WindowZOrderMode, usize)>,
62     /// 窗口字典
63     pub windows: BTreeMap<usize, Window>,
64 
65     /// 鼠标x坐标
66     pub cursor_x: i32,
67     /// 鼠标y坐标
68     pub cursor_y: i32,
69     /// 鼠标状态
70     pub cursor_i: CursorKind,
71 
72     /// 待处理的事件数组
73     events: Vec<Event>,
74 }
75 
76 impl WindowManager {
77     /// 创建窗口管理器
78     pub fn new() {
79         let window_manager = WindowManager {
80             data: RwLock::new(WindowManagerData {
81                 next_id: 0,
82                 _hover: None,
83                 order: VecDeque::new(),
84                 zbuffer: Vec::new(),
85                 windows: BTreeMap::new(),
86                 cursor_x: SCREEN_WIDTH as i32 / 2,
87                 cursor_y: SCREEN_HEIGHT as i32 / 2,
88                 cursor_i: CursorKind::None,
89                 events: Vec::new(),
90             }),
91         };
92 
93         unsafe {
94             WINDOW_MANAGER = Some(Arc::new(window_manager));
95         }
96 
97         // println!("[Init] Window_Manager created successfully!");
98     }
99 
100     /// # 函数功能
101     /// 新建窗口
102     ///
103     /// ## 参数
104     /// - x: 窗口左上角x坐标
105     /// - y: 窗口左上角y坐标
106     /// - width: 窗口宽度
107     /// - height: 窗口高度
108     /// - flags: 窗口属性
109     /// - title: 窗口标题
110     ///
111     /// ## 返回值
112     /// 窗口id
113     pub fn window_new(
114         &self,
115         mut x: i32,
116         mut y: i32,
117         width: i32,
118         height: i32,
119         _flags: &str,
120         _title: String,
121         image_path: &[u8],
122     ) {
123         let mouse_update_event: MouseUpdateEvent;
124 
125         {
126             let compositor = compositor().unwrap();
127             let mut guard = self.data.write().unwrap();
128 
129             let id = guard.next_id as usize; // 新窗口的id
130             guard.next_id += 1;
131 
132             if guard.next_id < 0 {
133                 guard.next_id = 1;
134             }
135 
136             if x < 0 && y < 0 {
137                 x = cmp::max(0, (SCREEN_WIDTH as i32 - width) / 2);
138                 y = cmp::max(0, (SCREEN_HEIGHT as i32 - height) / 2);
139             }
140 
141             // TODO 传入正确的scale
142             // TODO 传入title
143             let window = Window::new(x, y, width, height, 1, image_path);
144 
145             // TODO 处理flags
146 
147             // TODO 重绘title_rect
148             compositor.request_redraw(window.rect());
149 
150             match window.zorder {
151                 WindowZOrderMode::Front | WindowZOrderMode::Normal => {
152                     guard.order.push_front(id);
153                 }
154                 WindowZOrderMode::Back => {
155                     guard.order.push_back(id);
156                 }
157             }
158 
159             guard.windows.insert(id, window);
160 
161             // 确保鼠标正确显示
162             mouse_update_event = MouseUpdateEvent {
163                 x: guard.cursor_x,
164                 y: guard.cursor_y,
165             };
166         }
167 
168         self.handle_mouse_update_event(mouse_update_event);
169     }
170 
171     /// 发送事件
172     pub fn send_event(&self, event: Event) {
173         let mut guard = self.data.write().unwrap();
174         guard.events.push(event);
175     }
176 
177     /// 发送事件数组
178     pub fn send_events(&self, mut events: Vec<Event>) {
179         let mut guard = self.data.write().unwrap();
180         guard.events.append(&mut events);
181     }
182 
183     /// 处理所有事件
184     pub fn handle_all_events(&self) {
185         let mut events: Vec<Event>;
186 
187         {
188             let mut guard = self.data.write().unwrap();
189             events = guard.events.clone();
190             guard.events.clear();
191         }
192 
193         while let Some(event) = events.pop() {
194             self.handle_event(event);
195         }
196     }
197 
198     /// # 函数功能
199     /// 处理事件
200     ///
201     /// ## 参数
202     /// 事件对象
203     pub fn handle_event(&self, event_union: Event) {
204         // println!("[Info] Window_Manager handle event {:?}", event_union.to_option());
205         match event_union.to_option() {
206             EventOption::MouseRelative(event) => self.handle_mouse_relative_event(event),
207             EventOption::Button(_event) => {}
208             unknown => println!("[Error] Unexpected event: {:?}", unknown),
209         }
210     }
211 
212     /// 处理鼠标相对移动事件
213     pub fn handle_mouse_relative_event(&self, event: MouseRelativeEvent) {
214         // TODO: 将事件传递给窗口,同时考虑窗口对鼠标位置的影响
215 
216         let cursor_x: i32;
217         let cursor_y: i32;
218 
219         {
220             let guard = self.data.read().unwrap();
221             cursor_x = guard.cursor_x;
222             cursor_y = guard.cursor_y;
223         }
224 
225         let max_x: i32 = SCREEN_WIDTH as i32;
226         let max_y: i32 = SCREEN_HEIGHT as i32;
227         let cursor_rect = self.cursor_rect();
228 
229         //防止鼠标出界
230         let x = cmp::max(
231             0,
232             cmp::min(max_x - cursor_rect.width(), cursor_x + event.dx),
233         );
234         let y = cmp::max(
235             0,
236             cmp::min(max_y - cursor_rect.height(), cursor_y - event.dy),
237         ); // 原点在左上角,向上为负
238 
239         self.handle_mouse_update_event(MouseUpdateEvent { x, y });
240     }
241 
242     /// 处理鼠标移动事件
243     pub fn handle_mouse_update_event(&self, event: MouseUpdateEvent) {
244         let /*mut*/ new_cursor = CursorKind::Normal;
245 
246         // TODO: 判断新的鼠标状态
247         // TODO: 处理拖拽等事件,传递给相应窗口
248 
249         self.update_cursor(event.x, event.y, new_cursor);
250     }
251 
252     /// # 函数功能
253     /// 更新鼠标状态
254     ///
255     /// ## 参数
256     /// - x: 鼠标x坐标
257     /// - y: 鼠标y坐标
258     /// - kind: 鼠标状态
259     fn update_cursor(&self, x: i32, y: i32, kind: CursorKind) {
260         // println!("[Info] Mouse_Input_Handler update cursor {:?} {:?} ", x, y);
261 
262         let old_cursor_x: i32;
263         let old_cursor_y: i32;
264         let old_cursor_i: CursorKind;
265 
266         {
267             let guard = self.data.read().unwrap();
268             old_cursor_x = guard.cursor_x;
269             old_cursor_y = guard.cursor_y;
270             old_cursor_i = guard.cursor_i;
271         }
272 
273         if kind != old_cursor_i || x != old_cursor_x || y != old_cursor_y {
274             let cursor_rect = self.cursor_rect();
275             compositor().unwrap().request_redraw(cursor_rect);
276 
277             {
278                 let mut guard = self.data.write().unwrap();
279                 guard.cursor_x = x;
280                 guard.cursor_y = y;
281                 guard.cursor_i = kind;
282             }
283 
284             let cursor_rect = self.cursor_rect();
285             compositor().unwrap().request_redraw(cursor_rect);
286         }
287     }
288 
289     /// # 函数功能
290     /// 获得鼠标位置的矩形区域
291     pub fn cursor_rect(&self) -> Rect {
292         let guard = self.data.read().unwrap();
293         let server = starry_server().unwrap();
294         let server_gaurd = server.data.read().unwrap();
295 
296         if let Some(image) = server_gaurd.cursors.get(&guard.cursor_i) {
297             return Rect::new(
298                 guard.cursor_x,
299                 guard.cursor_y,
300                 image.width(),
301                 image.height(),
302             );
303         }
304 
305         return Rect::new(guard.cursor_x, guard.cursor_y, 0, 0);
306     }
307 
308     /// 更新zbuffer
309     pub fn rezbuffer(&self) {
310         let mut guard = self.data.write().unwrap();
311 
312         guard.zbuffer.clear();
313 
314         let len = guard.order.len();
315         for index in 0..len {
316             let id = guard.order[index];
317             let window_z = guard
318                 .windows
319                 .get(&index)
320                 .expect("窗口不存在!")
321                 .zorder
322                 .clone();
323             guard.zbuffer.push((id, window_z, index));
324         }
325 
326         guard.zbuffer.sort_by(|a, b| b.1.cmp(&a.1));
327     }
328 }
329