use std::{ cmp, collections::{BTreeMap, VecDeque}, sync::{Arc, RwLock}, }; use starry_client::base::event::{Event, EventOption, MouseRelativeEvent, MouseUpdateEvent}; use crate::{ base::{ rect::Rect, window::{Window, WindowZOrderMode}, }, core::{SCREEN_HEIGHT, SCREEN_WIDTH}, }; use super::{compositor::compositor, starry_server}; static mut WINDOW_MANAGER: Option> = None; pub fn window_manager() -> Option> { unsafe { WINDOW_MANAGER.clone() } } /// 鼠标样式 #[allow(dead_code)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum CursorKind { /// 无/不显示 None, /// 默认状态 Normal, /// 左下角 BottomLeftCorner, /// 右下角 BottomRightCorner, /// 下边界 BottomSide, /// 左边界 LeftSide, /// 右边界 RightSide, } /// 窗口管理器 #[allow(dead_code)] pub struct WindowManager { /// 数据锁 pub data: RwLock, } #[allow(dead_code)] pub struct WindowManagerData { /// 下一个窗口的id值 next_id: isize, /// TODO _hover: Option, /// 窗口顺序 pub order: VecDeque, /// 窗口顺序信息(下标index,模式,窗口id) pub zbuffer: Vec<(usize, WindowZOrderMode, usize)>, /// 窗口字典 pub windows: BTreeMap, /// 鼠标x坐标 pub cursor_x: i32, /// 鼠标y坐标 pub cursor_y: i32, /// 鼠标状态 pub cursor_i: CursorKind, /// 待处理的事件数组 events: Vec, } impl WindowManager { /// 创建窗口管理器 pub fn new() { let window_manager = WindowManager { data: RwLock::new(WindowManagerData { next_id: 0, _hover: None, order: VecDeque::new(), zbuffer: Vec::new(), windows: BTreeMap::new(), cursor_x: SCREEN_WIDTH as i32 / 2, cursor_y: SCREEN_HEIGHT as i32 / 2, cursor_i: CursorKind::None, events: Vec::new(), }), }; unsafe { WINDOW_MANAGER = Some(Arc::new(window_manager)); } // println!("[Init] Window_Manager created successfully!"); } /// # 函数功能 /// 新建窗口 /// /// ## 参数 /// - x: 窗口左上角x坐标 /// - y: 窗口左上角y坐标 /// - width: 窗口宽度 /// - height: 窗口高度 /// - flags: 窗口属性 /// - title: 窗口标题 /// /// ## 返回值 /// 窗口id pub fn window_new( &self, mut x: i32, mut y: i32, width: i32, height: i32, _flags: &str, _title: String, image_path: &[u8], ) { let mouse_update_event: MouseUpdateEvent; { let compositor = compositor().unwrap(); let mut guard = self.data.write().unwrap(); let id = guard.next_id as usize; // 新窗口的id guard.next_id += 1; if guard.next_id < 0 { guard.next_id = 1; } if x < 0 && y < 0 { x = cmp::max(0, (SCREEN_WIDTH as i32 - width) / 2); y = cmp::max(0, (SCREEN_HEIGHT as i32 - height) / 2); } // TODO 传入正确的scale // TODO 传入title let window = Window::new(x, y, width, height, 1, image_path); // TODO 处理flags // TODO 重绘title_rect compositor.request_redraw(window.rect()); match window.zorder { WindowZOrderMode::Front | WindowZOrderMode::Normal => { guard.order.push_front(id); } WindowZOrderMode::Back => { guard.order.push_back(id); } } guard.windows.insert(id, window); // 确保鼠标正确显示 mouse_update_event = MouseUpdateEvent { x: guard.cursor_x, y: guard.cursor_y, }; } self.handle_mouse_update_event(mouse_update_event); } /// 发送事件 pub fn send_event(&self, event: Event) { let mut guard = self.data.write().unwrap(); guard.events.push(event); } /// 发送事件数组 pub fn send_events(&self, mut events: Vec) { let mut guard = self.data.write().unwrap(); guard.events.append(&mut events); } /// 处理所有事件 pub fn handle_all_events(&self) { let mut events: Vec; { let mut guard = self.data.write().unwrap(); events = guard.events.clone(); guard.events.clear(); } while let Some(event) = events.pop() { self.handle_event(event); } } /// # 函数功能 /// 处理事件 /// /// ## 参数 /// 事件对象 pub fn handle_event(&self, event_union: Event) { // println!("[Info] Window_Manager handle event {:?}", event_union.to_option()); match event_union.to_option() { EventOption::MouseRelative(event) => self.handle_mouse_relative_event(event), EventOption::Button(_event) => {} unknown => println!("[Error] Unexpected event: {:?}", unknown), } } /// 处理鼠标相对移动事件 pub fn handle_mouse_relative_event(&self, event: MouseRelativeEvent) { // TODO: 将事件传递给窗口,同时考虑窗口对鼠标位置的影响 let cursor_x: i32; let cursor_y: i32; { let guard = self.data.read().unwrap(); cursor_x = guard.cursor_x; cursor_y = guard.cursor_y; } let max_x: i32 = SCREEN_WIDTH as i32; let max_y: i32 = SCREEN_HEIGHT as i32; let cursor_rect = self.cursor_rect(); //防止鼠标出界 let x = cmp::max( 0, cmp::min(max_x - cursor_rect.width(), cursor_x + event.dx), ); let y = cmp::max( 0, cmp::min(max_y - cursor_rect.height(), cursor_y - event.dy), ); // 原点在左上角,向上为负 self.handle_mouse_update_event(MouseUpdateEvent { x, y }); } /// 处理鼠标移动事件 pub fn handle_mouse_update_event(&self, event: MouseUpdateEvent) { let /*mut*/ new_cursor = CursorKind::Normal; // TODO: 判断新的鼠标状态 // TODO: 处理拖拽等事件,传递给相应窗口 self.update_cursor(event.x, event.y, new_cursor); } /// # 函数功能 /// 更新鼠标状态 /// /// ## 参数 /// - x: 鼠标x坐标 /// - y: 鼠标y坐标 /// - kind: 鼠标状态 fn update_cursor(&self, x: i32, y: i32, kind: CursorKind) { // println!("[Info] Mouse_Input_Handler update cursor {:?} {:?} ", x, y); let old_cursor_x: i32; let old_cursor_y: i32; let old_cursor_i: CursorKind; { let guard = self.data.read().unwrap(); old_cursor_x = guard.cursor_x; old_cursor_y = guard.cursor_y; old_cursor_i = guard.cursor_i; } if kind != old_cursor_i || x != old_cursor_x || y != old_cursor_y { let cursor_rect = self.cursor_rect(); compositor().unwrap().request_redraw(cursor_rect); { let mut guard = self.data.write().unwrap(); guard.cursor_x = x; guard.cursor_y = y; guard.cursor_i = kind; } let cursor_rect = self.cursor_rect(); compositor().unwrap().request_redraw(cursor_rect); } } /// # 函数功能 /// 获得鼠标位置的矩形区域 pub fn cursor_rect(&self) -> Rect { let guard = self.data.read().unwrap(); let server = starry_server().unwrap(); let server_gaurd = server.data.read().unwrap(); if let Some(image) = server_gaurd.cursors.get(&guard.cursor_i) { return Rect::new( guard.cursor_x, guard.cursor_y, image.width(), image.height(), ); } return Rect::new(guard.cursor_x, guard.cursor_y, 0, 0); } /// 更新zbuffer pub fn rezbuffer(&self) { let mut guard = self.data.write().unwrap(); guard.zbuffer.clear(); let len = guard.order.len(); for index in 0..len { let id = guard.order[index]; let window_z = guard .windows .get(&index) .expect("窗口不存在!") .zorder .clone(); guard.zbuffer.push((id, window_z, index)); } guard.zbuffer.sort_by(|a, b| b.1.cmp(&a.1)); } }