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