1 use std::{ 2 cell::{Cell, RefCell}, 3 sync::Arc, 4 }; 5 6 use starry_client::{ 7 base::{ 8 color::Color, 9 renderer::{RenderMode, Renderer}, 10 }, 11 window::Window, 12 }; 13 14 use crate::{traits::focus::Focus, widgets::Widget}; 15 16 use super::rect::Rect; 17 18 /// 面板渲染器 19 pub struct PanelRenderer<'a> { 20 /// 客户端窗口 21 window: &'a mut Window, 22 } 23 24 impl<'a> PanelRenderer<'a> { 25 pub fn new(window: &'a mut Window) -> Self { 26 PanelRenderer { window } 27 } 28 } 29 30 impl<'a> Renderer for PanelRenderer<'a> { 31 fn width(&self) -> u32 { 32 self.window.width() 33 } 34 35 fn height(&self) -> u32 { 36 self.window.height() 37 } 38 39 fn data(&self) -> &[Color] { 40 self.window.data() 41 } 42 43 fn data_mut(&mut self) -> &mut [Color] { 44 self.window.data_mut() 45 } 46 47 fn sync(&mut self) -> bool { 48 self.window.sync() 49 } 50 51 fn mode(&self) -> &Cell<RenderMode> { 52 &self.window.mode() 53 } 54 55 // TODO 56 // fn char(&mut self, x: i32, y: i32, c: char, color: Color) { 57 // } 58 } 59 60 impl<'a> Drop for PanelRenderer<'a> { 61 fn drop(&mut self) { 62 self.window.sync(); 63 } 64 } 65 66 /// UI面板类作为容器管理一组UI组件(UI-Widget) 67 /// 拥有一个窗口对象用于渲染和事件传递 68 pub struct Panel { 69 /// 客户端窗口对象 70 window: RefCell<Window>, 71 /// 子组件数组 72 pub widgets: RefCell<Vec<Arc<dyn Widget>>>, 73 /// 窗口是否打开 74 pub running: Cell<bool>, 75 /// 当前聚焦的窗口 76 pub focused_widget: RefCell<Option<Arc<dyn Widget>>>, 77 } 78 79 impl Panel { 80 pub fn new(rect: Rect, title: &str) -> Self { 81 Panel::from_window(Window::new(rect.x, rect.y, rect.width, rect.height, title)) 82 } 83 84 pub fn from_window(window: Window) -> Self { 85 Panel { 86 window: RefCell::new(window), 87 widgets: RefCell::new(Vec::new()), 88 running: Cell::new(true), 89 focused_widget: RefCell::new(None), 90 } 91 } 92 93 /// 获得客户端窗口对象 94 pub fn into_window(self) -> Window { 95 self.window.into_inner() 96 } 97 98 /// 返回x坐标 99 pub fn x(&self) -> i32 { 100 let window = self.window.borrow(); 101 (*window).x() 102 } 103 104 /// 返回y坐标 105 pub fn y(&self) -> i32 { 106 let window = self.window.borrow(); 107 (*window).y() 108 } 109 110 /// 返回宽度值 111 pub fn width(&self) -> u32 { 112 let window = self.window.borrow(); 113 (*window).width() 114 } 115 116 /// 返回高度值 117 pub fn height(&self) -> u32 { 118 let window = self.window.borrow(); 119 (*window).height() 120 } 121 122 /// 窗口标题 123 pub fn title(&self) -> String { 124 let window = self.window.borrow(); 125 (*window).title() 126 } 127 128 /// 改变窗口位置 129 pub fn set_pos(&self, x: i32, y: i32) { 130 let mut window = self.window.borrow_mut(); 131 (*window).set_pos(x, y); 132 } 133 134 /// 改变窗口大小 135 pub fn set_size(&self, width: u32, height: u32) { 136 let mut window = self.window.borrow_mut(); 137 (*window).set_size(width, height); 138 } 139 140 /// 改变窗口标题 141 pub fn set_title(&self, title: &str) { 142 let mut window = self.window.borrow_mut(); 143 (*window).set_title(title); 144 } 145 146 /// 关闭窗口 147 pub fn close(&self) { 148 self.running.set(false); 149 } 150 151 /// 添加子组件,返回子组件id 152 pub fn add_child<T: Widget>(&self, widget: &Arc<T>) -> usize { 153 let mut widgets = self.widgets.borrow_mut(); 154 let id = widgets.len(); 155 widgets.push(widget.clone()); 156 157 return id; 158 } 159 160 /// 渲染面板(渲染子组件数组) 161 pub fn draw(&self) { 162 let mut window = self.window.borrow_mut(); 163 let mut renderer = PanelRenderer::new(&mut window); 164 165 for widget in self.widgets.borrow().iter() { 166 self.draw_widget(&mut renderer, widget); 167 } 168 169 renderer.sync(); 170 } 171 172 /// 渲染单个组件 173 pub fn draw_widget(&self, renderer: &mut dyn Renderer, widget: &Arc<dyn Widget>) { 174 widget.update(); 175 widget.draw(renderer, self.is_focused(widget)); 176 177 // 渲染子组件 178 for child in widget.children().borrow().iter() { 179 self.draw_widget(renderer, child); 180 } 181 } 182 } 183 184 impl Focus for Panel { 185 fn focused_widget(&self) -> RefCell<Option<Arc<dyn Widget>>> { 186 self.focused_widget.clone() 187 } 188 189 fn focus(&self, widget: &Arc<dyn Widget>) { 190 (*self.focused_widget.borrow_mut()) = Some(widget.clone()); 191 } 192 } 193