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(0, cmp::min(max_x - cursor_rect.width(), cursor_x + event.dx)); 231 let y = cmp::max(0, cmp::min(max_y - cursor_rect.height(), cursor_y - event.dy)); // 原点在左上角,向上为负 232 233 self.handle_mouse_update_event(MouseUpdateEvent { x, y }); 234 } 235 236 /// 处理鼠标移动事件 237 pub fn handle_mouse_update_event(&self, event: MouseUpdateEvent) { 238 let /*mut*/ new_cursor = CursorKind::Normal; 239 240 // TODO: 判断新的鼠标状态 241 // TODO: 处理拖拽等事件,传递给相应窗口 242 243 self.update_cursor(event.x, event.y, new_cursor); 244 } 245 246 /// # 函数功能 247 /// 更新鼠标状态 248 /// 249 /// ## 参数 250 /// - x: 鼠标x坐标 251 /// - y: 鼠标y坐标 252 /// - kind: 鼠标状态 253 fn update_cursor(&self, x: i32, y: i32, kind: CursorKind) { 254 // println!("[Info] Mouse_Input_Handler update cursor {:?} {:?} ", x, y); 255 256 let old_cursor_x: i32; 257 let old_cursor_y: i32; 258 let old_cursor_i: CursorKind; 259 260 { 261 let guard = self.data.read().unwrap(); 262 old_cursor_x = guard.cursor_x; 263 old_cursor_y = guard.cursor_y; 264 old_cursor_i = guard.cursor_i; 265 } 266 267 if kind != old_cursor_i || x != old_cursor_x || y != old_cursor_y { 268 let cursor_rect = self.cursor_rect(); 269 compositor().unwrap().request_redraw(cursor_rect); 270 271 { 272 let mut guard = self.data.write().unwrap(); 273 guard.cursor_x = x; 274 guard.cursor_y = y; 275 guard.cursor_i = kind; 276 } 277 278 let cursor_rect = self.cursor_rect(); 279 compositor().unwrap().request_redraw(cursor_rect); 280 } 281 } 282 283 /// # 函数功能 284 /// 获得鼠标位置的矩形区域 285 pub fn cursor_rect(&self) -> Rect { 286 let guard = self.data.read().unwrap(); 287 let server = starry_server().unwrap(); 288 let server_gaurd = server.data.read().unwrap(); 289 290 if let Some(image) = server_gaurd.cursors.get(&guard.cursor_i) { 291 return Rect::new( 292 guard.cursor_x, 293 guard.cursor_y, 294 image.width(), 295 image.height(), 296 ); 297 } 298 299 return Rect::new(guard.cursor_x, guard.cursor_y, 0, 0); 300 } 301 302 /// 更新zbuffer 303 pub fn rezbuffer(&self) { 304 let mut guard = self.data.write().unwrap(); 305 306 guard.zbuffer.clear(); 307 308 let len = guard.order.len(); 309 for index in 0..len { 310 let id = guard.order[index]; 311 let window_z = guard 312 .windows 313 .get(&index) 314 .expect("窗口不存在!") 315 .zorder 316 .clone(); 317 guard.zbuffer.push((id, window_z, index)); 318 } 319 320 guard.zbuffer.sort_by(|a, b| b.1.cmp(&a.1)); 321 } 322 } 323